I would like to specify my routing tables such that they would feel much more "natural"
/Products /Product/17 /Product/Edit/17 /Product/Create
Close to the defaults configuration but such that "Index" action would be mapped to the multiples form of the controller name and "Details" action would be mapped directly with an id of the item directly following the controller name.
I know I can achieve this by explicitly defining special routing mappings like this:
routes.MapRoute(
"ProductsList",
"Products",
new { controller = "Product", action = "Index" }
);
routes.MapRoute(
"ProductDetails",
"Product/{id}",
new { controller = "Product", action = "Details" }
);
/*
* Ditto for all other controllers
*/
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
The code above is way too verbose for my tastes and has the downside that each controller needs to be mentioned at least twice to prevasively apply this url pattern.
Is there some way to generalize this or am I bound to manual labour in this case?
You can try something like this:
routes.MapRoute(
"ProductsList",
"{pluralizedControllerName}",
new { controller = "Home", action = "Index" },
new { pluralizedControllerName = new PluralConstraint() }
);
routes.MapRoute(
"ProductDetails",
"{controller}/{id}",
new { controller = "Home", action = "Details" },
new { id = @"\d+" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Notice the constraint in second route, it ensures that /Product/Create
doesn't get picked by second route so that it gets mapped as third.
For route testing you can use routedebugger, and for writing unit test for routes try MvcContrib-TestHelper. You can get both with NuGet.
EDIT:
You can use this simple pluralizer and then implement something like this:
public class PluralConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
List<string> names = GetControllerNames();//get all controller names from executing assembly
names.ForEach(n => n.Pluralize(n));
return names.Contains(values[parameterName]);
}
}
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