ASP.NET MVC2 Route Constraint - optional number id parameter
I have a default route set up in my ASP.NET MVC2 project and would like to add/modify it for some of my other controllers. Lets say I have a Customer controller with Details action that expects and "id" parameter (int). For example:
//
// GET: /Customer/Details/5
public ActionResult Details(int id)
{
//...
}
How can I add a route that will return a 404 if a user enters a "non-number"? I tried adding following "before" default route but it did not work...
routes.MapRoute(
"DefaultDigitsId", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index" },
new { id = @"\d+" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", actio开发者_JS百科n = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Note, I would like, if possible, to keep default route... All of my controllers use "Details" and "Edit" where "id" (int) parameter is required.. I am wondering if there is a way to accomplish this without having to specify multiple routes (i.e. something generic)...And of course, the goal is that if user enters something like "/Customer/Details/apple" it does not throw an error but takes them to Error page...
There is also this post that hints to setting a default value but I am not sure how to do it...
I haven't tried this, but you might want to give it a try:
routes.MapRoute(
"DefaultDetails",
"{controller}/Details/{id}",
new { controller = "Home", action = "Details" },
new { id = @"\d+" }
);
routes.MapRoute(
"DefaultEdit",
"{controller}/Edit/{id}",
new { controller = "Home", action = "Edit" },
new { id = @"\d+" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I would expect that "Customer/Details/1" uses the first route (which validates the id as a number, a call to "Customer/Edit/1" uses the second, which does likewise, and a call to "Customer/Buy/Orange" uses the third route, which doesn't try to validate IDs in this way. Did I understand what you're trying to do correctly? Let me know if this approach works.
Add an IgnoreRoute after the one that matches a numeric id that will ignore any requests to the Details action on the Customer controller:
routes.MapRoute(
"DefaultDigitsId", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index" },
new { id = @"\d+" } // match numeric id
);
routes.IgnoreRoute("Customer/Details/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Any value that cannot be parsed to a string will make the id value be null on call, so you could redirect to the error page if the id is not null.
Another possibility is registering a global filter that checks if there's a parameter named id and if it is null, then redirects to the error page
精彩评论