问题
I am struggling to get my head around routing in MVC3.
Previously I have generally just avoided the whole area and stuck with ugly old ?id=1&foo=bar
type urls. Not nice.
I have 4 routes defined thusly
routes.MapRoute("Blog", "{controller}/{action}/{PageNumber}/{PostsPerPage}", new { controller = "blog", action = "list", PageNumber = UrlParameter.Optional, PostsPerPage = UrlParameter.Optional });
routes.MapRoute("Code", "{controller}/{action}/{title}", new { });
routes.MapRoute("Id", "{controller}/{action}/{id}", new { });
routes.MapRoute("Default", "{controller}/{action}", new { controller = "home", action = "index" });
I have tried to order them from most specific to least.
The first 'blog' route works fine and I can use a URL like /blog/list/2/5
and it maps correctly to my controller.
The default route at the bottom is also working as I would expect.
However if I have action methods like this:
public ActionResult BarX(int id)
{
//some stuff
}
public ActionResult BarY(string title)
{
//some stuff
}
I would expect it to use the third route and produce a URL like /foo/barX/3
.
Yet if I use
@Html.ActionLink("TEST1", "barX", "foo", new { id = 3 }, null)
the URL generated is
/foo/barx?id=3
Similarly the URL generated for
@Html.ActionLink("TEST2", "barY", "foo", new { title = "test" }, null)
is
/foo/bary?title=test
So I guess my question is: why are they producing URLs with the old ?id=
syntax and not /foo/barx/3
?
回答1:
All of your routes are basically the same. They are
{controller}/{action}/{param}/{param}
I say the same because the routing engine would not understand the difference between {controller}/{action}/{id}
and {controller}/{action}/{title}
and the route engine would really just see
{controller}/{action}/{PageNumber}/{PostsPerPage}
and confuse all the routes with the first one.
Once the route engine sees your almost generic {optional}/{optional}/{optional}/{optional}/
route at the top, anything with 4 or fewer elements can fit it so it goes no further.
If, on the other hand, your routes had distinctive beginnings, rather than generic {Controller}
:
routes.MapRoute("Blog", "Blog/{PageNumber}/{PostsPerPage}", new { controller = "blog", action = "list", PageNumber = UrlParameter.Optional, PostsPerPage = UrlParameter.Optional });
routes.MapRoute("Code", "Code/{title}", new { controller = "code", action = "list", title = UrlParameter.Optional });
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "home", action = "index", id = UrlParameter.Optional });
Now, every time the routing engine sees Blog/...
it understands that only 1 route can match. With all others, it will move on looking for a match. Whenever it sees Code/...
, again only 1 route is a match. And Default will handle anything like {Controller}/{Action}/{id}
that doesn't have Blog
or Code
as a first route param.
来源:https://stackoverflow.com/questions/15605945/mvc3-routes-with-different-parameter-types