I have an ASP.Net application which has an area called 'Customers'. This area has a controller with the same name with a single method called Index.
I have the following route defined:
context.MapRoute(null,
"Customers/{controller}/{action}",
new { controller = "customers", action = "Index" }
);
This allows my to navigate to use the following URL to navigate to the index method on my Customers controller.
MyDomain/Customers
In my customer area I also have another controller called products. This has a number of methods that allow me to work with product entities (mostly auto-generated by Visual Studio at the moment).
With my current route I can navigate to the products controller using URL's like this:
MyDomain/Customers/Products (shows the index page of the products controller) MyDomain/Customers/Products/Create (Shows a page to add new products). MyDomain/Customers/Products/Details?id=1234 (Show the product with the id of 1234)
Now what I want to be able to do is navigate to the details page with a much more user friendly URL such as:
MyDomain/Customers/Products/1234
I have defined a new route that look like this:
context.MapRoute(null,
"Customers/Products/{id}",
new { controller = "Products", action = "Details" }
);
The route is defined before the first route I demonstrated. This allows me to navigate to the products page as I want, however I can no longer navigate to other methods on my products controller.
E.G. The following URL
MyDomain/Customers/Products/Create
Gives me the following error:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult Details(Int32)'
If I change the order of the routes then I can navigate to all the methods on my products controller but my details URL reverts to the old format of having a query parameter.
If I update the route to look like this:
context.MapRoute(null,
"Customers/Products/{id}",
new { controller = "Products", action = "Details", id = UrlParameter.Optional }
);
Then I still get the same problem.
Can anyone tell me how to structure my routes to get the result I want? In summary:
Routing in ASP.NET MVC cs file in App_Start Folder, You can define Routes in that file, By default route is: Home controller - Index Method. routes. MapRoute has attributes like name, url and defaults like controller name, action and id (optional).
The Default route maps the first segment of a URL to a controller name, the second segment of a URL to a controller action, and the third segment to a parameter named id. The Default route maps this URL to the following parameters: controller = Home. action = Index.
ActionName attribute is an action selector which is used for a different name of the action method. We use ActionName attribute when we want that action method to be called with a different name instead of the actual name of the method.
While ASP.NET MVC will allow you to have two actions with the same name, . NET won't allow you to have two methods with the same signature - i.e. the same name and parameters. You will need to name the methods differently use the ActionName attribute to tell ASP.NET MVC that they're actually the same action.
If the ID is always going to be an int then you can add a constraint to the route like this:
context.MapRoute(null,
"Customers/Products/{id}",
new {controller = "Products", action = "Details", id = UrlParameter.Optional},
new {id = @"\d+"} // Constraint to only allow numbers
);
Try something like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Products_Details",
"Customers/Products/{id}",
new { controller="Products", action="Details" },
new { id = @"\d+" }
);
context.MapRoute(
"Customers_default",
"Customers/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Update: added constraint on route.
Explanation: The first route maps to your details page and forces the user to provide an id that has the format of numbers (the last parameter in the first MapRoute
). If the id doesn't have the format \d+
it will not match the route and the default will be used. This will give you the following routes:
Customers\Products (index)
Customers\Products\1234 (details of 1234)
Customers\Products\Create (create page for products)
Customers\Products\Edit\1234 (edit page for 1234)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With