How to ignore current route values when generating links?

一曲冷凌霜 提交于 2020-01-10 08:50:10

问题


The question is similar to asp.net mvc Html.ActionLink() keeping route value I don't want, but with a twist that makes it more complex.

Starting from a default new MVC3 app, I change the routes to:

routes.MapRoute(
    "r1", // Route name
    "{controller}/{id}/{action}"
);

routes.MapRoute(
    "r2", // Route name
    "{controller}/{action}"
);

Notice that the id comes before the action in the first.

Then in Home\Index.cshtml, I add:

@Url.Action("Index")
@Url.Action("Index", new { id = "blah" })
@Url.Action("Index", new { id = "" })

Now I navigate to /Home/Foo/Index and look at the 3 generated links. I get

  1. "/Home/Foo/Index"
  2. "/Home/blah/Index"
  3. "/Home/Index?id=Foo"

The first two make sense, and are using the first route.

But in the third link, which hits the second route, I don't understand why id=Foo is passed on the query string, given that I explicitly passed an empty id. I would expect it to just generate "/Home/Index".

Can anyone explain that, and suggest how I can get it not to show up?


回答1:


I just tested this and it seems to work ok.

Url.Action("Index", new { id = UrlParameter.Optional })

generates

/Home/Index



回答2:


To solve it in this case is quite easy if yo don't care how it's solved.

Change the third link to:

@Url.RouteUrl("R2")

which gives me:

  • /Home/Foo/Index
  • /Home/blah/Index
  • /Home/Index

Why it happends in the first case is something I have yet to figure out. I have been bitten by this too but mostly when it comes to forms.

UPDATE 1:

I was digging around the MVC source and created a few tests that reproduced this problem. The problem seems to be when

RouteCollection.GetVirtualPath(requestContext, correctedValues);

is run. It creates a querystring with the old id. Exactly why I couldn't tell as that class isn't located in the MVC source.




回答3:


This is probably not the answer you're looking for, but using Url.Route instead of Url.Action seems to work:

@Url.RouteUrl("r2")

This generates /Home/Index

Update

Phil Haack recommendeds generating URLs using the route name:

This might seem like a big problem, but the fix is actually very simple. Use names for all your routes and always use the route name when generating URLs. Most of the time, letting routing sort out which route you want to use to generate an URL is really leaving it to chance. When generating an URL, you generally know exactly which route you want to link to, so you might as well specify it by name.




回答4:


Because r2 does not define the id parameter to be a part of the URL? If you change it to {controller}/{action}/{id}, it will be fine. You'll see the same behaviour if you change r2 to not include action: action will then also becoe a query variable.

The fact that you explicitly set it to "" means that routing will take it into account anyway. Just don't add id and you'll be fine when generating a link.



来源:https://stackoverflow.com/questions/6530220/how-to-ignore-current-route-values-when-generating-links

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!