I'm having trouble getting a Route working in order to constrain the parameters of an action of a controller to only be integers.
I have a a controller action as follows:
[RequiresRole(RoleToCheckFor = "Administrator"), AcceptVerbs(HttpVerbs.Get)]
public ActionResult Edit(int id)
{
...
}
and the following routes in Global.asax.cs:
routes.MapRoute(
"UserEdit",
"user/edit/{id}",
new {controller = "user", action = "edit"},
new {id = @"\d+"}
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
routes.MapRoute("Error",
"{*url}",
new { controller = "Error", action = "notfound" });
I'm therefore expecting that if i enter http://domain.com/user/edit/ABCD i shouldn't get the following usual error:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)'
This (i think) is precisely what is al开发者_C百科so said at http://www.asp.net/%28S%28pdfrohu0ajmwt445fanvj2r3%29%29/learn/mvc/tutorial-24-cs.aspx
However, i'm still seeing the "...null entry..." error.
Any ideas why this is so? Am i doing something wrong with the route setup?
Thanks
your second route
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
is catching it and is unconstrained.
Use Phil Haacks route debugger for such issues
As Paul points out, the route is correctly being skipped because the constraint isn't matching. Thus, the routing system continues to the next route and tries to match it. Because the second route is not constrained, it will match and be processed.
There are a number of ways to work around this.
One of the simplest ways is to remove the constraint from the route and to do the parameter validation checkin in the controller action.
Another way is to add an additional route immediately after the edit route that serves to display errors:
routes.MapRoute(
"UserEditError",
"user/edit/{id}",
new {controller = "user", action = "EditError"}
);
Note that this route has no constraint on it and goes to an EditError action. This way you might be able to provide better errors for people who type in invalid URLs.
A mistake I always manage to make is to put
controller = "HomeController"
instead of controller = "Home"
. That'll break your routes every time :-)
context.MapRoute(
name: "RedirectAll",
url: "{*url}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { typeof(HomeController).Namespace },
constraints: new { host = new HostConstraint("defenderrazor.com") });
精彩评论