Route configuration looking for an id in my URL - c#

How do I correct my routing to fix an issue with ajax .load()
I modified my route to my spacecontroller so that it looks like this
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
);
so that I have a cleaner route and when a user wants to see a space the URL will look like this
www.mysite/space/12345
the problem I'm having now is when my JS file calls a .load() like this, , where spaceoverview is my action
$("#partialPageContainer").load('/Space/SpaceOverview', function (response, status, xhr) {
alert("Load was performed.");
});
I get an error saying
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'YogaBandy2017.Controllers.SpaceController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
So I have to put an id after the url like this, which is not what I want, or doesn't seem right to me
How can I fix this or is this just how the routing works? I'm kinda new to mvc routing with ASP.Net
$("#partialPageContainer").load('/Space/SpaceOverview/1', function (response, status, xhr) {
alert("Load was performed.");
});
UPDATED - I guess for now I'll just use '/space/actionname/1' to connect to each action, until I can find a better solution.

You can use parameter constraints to filter out string values for the id parameter.
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
constraints: new { id = #"\d+" }
);
Then you need to have your default route set up to handle things that don't match that constraint:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The first route will catch your
/Space/12345
example, because 12345 matches the #"\d+" pattern, however the second route will handle your
/Space/SpaceOverview
example, because SpaceOverview does not.
You can find more information and examples of route constraints here: https://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs
edit: I believe you can also use one of the built in routing constraints (which might work better, because technically a value could match the #"\d+" pattern but still not be a valid int), like this:
routes.MapRoute(
name: "SpaceCleanRoute",
url: "Space/{id}",
defaults: new { controller = "Space", action = "Index" }
constraints: new { id = new System.Web.Http.Routing.Constraints.IntRouteConstraint()}
);

If you want to send action parameter try this:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Related

How do I force a redirect with a parameter?

I have a parameter value which I have to URL encode. Therefore my understanding is that it must be sent as a query string on the end of the URL rather than part of the main URL. I have successfully tested this by directly pasting the URL into the browser.
I am trying to redirect to a URL of:
Server/Application/Area/Controller/Action/?id=xyz
But when I use
return RedirectToAction("Action", "Controller", new { area = "Area", id = Url.Encode(uniqueId) });
I am sent to
Server/Application/Area/Controller/Action/xyz
How do I stop this happening?
It happens because of your default route is;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Site", action = "Index", id = UrlParameter.Optional }
);
if you want to keep using this route, you should be have to change your id parameter in your url.
But if id parameter is omitted from the default route, your action redirected as you expect.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Site", action = "Index"}
);
Remove id from Default Route
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
or change the name of your parameter from id to something else.
I hope this will help.

The parameters dictionary contains a null entry for parameter 'id' when change in Routing

I have done Routing in my routeConfig file as below.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Search",
url: "{controller}/{action}/{department}/{name}",
defaults: new { controller = "Search", action = "Result",name =UrlParameter.Optional}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I want only name parameter should be optional, so made this this by writing
name =UrlParameter.Optional
But now when I click on this link
#Html.ActionLink("Edit", "EditEmployee", new { id = item.Id })
It gives me exception "The parameters dictionary contains a null entry for parameter 'id'"
Case 1:
but when I do this,
defaults: new { controller = "Search", action = "Result"}
Removing name optional, It works fine.
case 2:
When I do this
defaults: new { controller = "Search", action = "Result", department =UrlParameter.Optional, name=UrlParameter.Optional}
making both parameter optional, also works fine , but now Url generating for Edit is as follow
http://localhost:12190/Home/EditEmployee?id=1
but I want clean URL like this
http://localhost:12190/Home/EditEmployee/1.
So How can get both,only name parameter optional and also a clean URL.
You've got two routes and it seems like you mixed them in your mind. The path you provided (http://localhost:12190/Home/EditEmployee?id=1) refers to the second route while department and name parameters - to the first one.
Maybe you need to comment the first route and try to get everything working with your set of parameters - action and id. Also you can try to use attribute routing to specify routes to your controllers and actions

default routing not working

In my MVC application, I have following route configuration,
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Now if i give some thing like this, localhost:56789/prd1/Home/Index
The first routing is working.
However if i directly access localhost:56789/Home/Index or any other controller action, like localhost:56789/Account/Login the routing is not working.
Is it because I have a {productName} defined?
For testing purpose how can I add few products like prd1, prd2 along with routing?
Routes are matched against the request in the order they are defined. When a route matching the request is found, no further routes are considered. Thus, you need to list your routes in order of decreasing specificity.
However, your first route matches more requests than your second route, i.e. it is less specific than the second route:
When ASP.NET MVC tries to match the request for Home/Index to your routes, it will match the first route because it will consider Home to be the productName, it will consider Index to be the controller name and the rest of the parameters are not required.
You need to reorder your routes or make the first route more specific. This could be done by putting constraints on the productName parameter.
UPDATE
Without knowing anything about your products and their names, it is impossible for me to suggest an appropriate constraint. Maybe you could use a numeric SKU and have a constraint like
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { productName = #"\d+" }
);
forcing productName to be numeric.
Alternatively, you could change the url to
"products/{productName}/{controller}/{action}/{id}"
For more on constraints see this link or use Google.
For route configuration
routes.MapRoute(
name: "ProductRoute",
url: "{productName}/{controller}/{action}/{id}",
defaults: new { productName = 'put your method name to get productName over here', controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "your namespace of controller" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

UrlHelper.Action method not mapping to correct route with first variable parameter

Let's look at these two routes mapped in RouteConfig.cs, one with a guid and one without:
// Non-guid route
routes.MapPageRoute(
name: null,
url: "dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
// Guid route
routes.MapPageRoute(
name: null,
url: "{guid}/dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
And the method call:
UrlHelper.Action("Index", "Dashboard", new { guid = "c73b47b9-4ad5-414a-a92e-8937231f8e2bD" })
The method returns this:
"/dashboard/?guid=c73b47b9-4ad5-414a-a92e-8937231f8e2b"
But I'm expecting this:
"/c73b47b9-4ad5-414a-a92e-8937231f8e2b/dashboard/"
Note that it's putting the guid as a querystring value instead of the first parameter.
Now if I hardcode that second url the app uses the correct guid route and also works if I use route names instead (UrlHelper.RouteUrl) so I don't think it's an issue with the route mappings themselves. Neither of these solutions will work well with our application as we have hundreds of routes and currently using UrlHelper.Action all over the place.
I've also tried pretty much every overload and variation of UrlHelper.Action, including passing a RouteValueDictionary instead of an anonymous object.
This is an ASP.NET MVC 4 web application.
Any ideas to why this isn't working? (or alternatives, maybe using one route)
Try this. Put the more specific route first:
routes.MapRoute(
name: "WithGUID",
url: "{guid}/dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index" }
);
routes.MapRoute(
name: "NoGUID",
url: "dashboard/{action}",
defaults: new { controller = "Dashboard", action = "Index", guid = "" }
);

Why do you need to specify the controller and action in the default route for the RoutesTable in ASP.NET MVC?

Why do we have to specify the defaults for the default route?
This is a normal default route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Why can't I just do this:
routes.MapRoute(
name: "Default",
url: "Home/Index/{id}",
defaults: new {id = UrlParameter.Optional }
);
I already specified the action and controller but when I use this way, I get an error. Does anyone know why you have to specify the action and controller in the default route?
Without a default set of parameters, how is routing supposed to know where to send this URL?
/
The defaults let you do that URL, so it knows to use the 'Home' controller's 'Index' method.
Or:
/Articles
In this case, the 'Index' action of the 'Articles' controller would be called. Without those defaults, again, routing has no way to know what to do.

Categories

Resources