生成链接时如何忽略当前路由值?

时间:2021-09-14 15:35:31

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.

这个问题类似于asp.net mvc Html.ActionLink(),它保留了我不想要的路由值,但有一个扭曲使得它更复杂。

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

从默认的新MVC3应用程序开始,我将路由更改为:

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.

请注意,id位于第一个操作之前。

Then in Home\Index.cshtml, I add:

然后在Home \ Index.cshtml中,我添加:

@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

现在我导航到/ Home / Foo / Index并查看3个生成的链接。我明白了

  1. "/Home/Foo/Index"
  2. “/首页/美孚/索引”
  3. "/Home/blah/Index"
  4. “/首页/胡说/索引”
  5. "/Home/Index?id=Foo"
  6. “/首页/指数?ID =富”

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".

但是在第三个链接中,遇到第二个路径,我不明白为什么id = Foo在查询字符串上传递,因为我明确地传递了一个空id。我希望它只是生成“/ Home / Index”。

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

任何人都可以解释这一点,并建议我如何让它不显示?

4 个解决方案

#1


19  

I just tested this and it seems to work ok.

我只是测试了它,似乎工作正常。

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

generates

生成

/Home/Index

#2


5  

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

这可能不是您正在寻找的答案,但使用Url.Route而不是Url.Action似乎有效:

@Url.RouteUrl("r2")

This generates /Home/Index

这会生成/ Home / Index

Update

更新

Phil Haack recommendeds generating URLs using the route name:

Phil Haack建议使用路由名称生成URL:

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.

这可能看起来像一个大问题,但修复实际上非常简单。使用所有路由的名称,并在生成URL时始终使用路由名称。大多数情况下,让路由选择你想要用来生成URL的路由实际上是让它失去了机会。生成URL时,通常可以确切地知道要链接到哪条路径,因此您也可以按名称指定它。

#3


5  

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:

更新1:

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

我正在挖掘MVC源代码并创建了一些可以重现这个问题的测试。问题似乎是什么时候

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.

运行。它使用旧id创建一个查询字符串。究竟为什么我不能说这个类不在MVC源中。

#4


1  

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.

因为r2没有将id参数定义为URL的一部分?如果您将其更改为{controller} / {action} / {id},则可以。如果将r2更改为不包含操作,您将看到相同的行为:操作也将使用查询变量。

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.

您明确将其设置为“”的事实意味着无论如何路由都会将其考虑在内。只是不添加id,生成链接时你会没事的。

#1


19  

I just tested this and it seems to work ok.

我只是测试了它,似乎工作正常。

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

generates

生成

/Home/Index

#2


5  

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

这可能不是您正在寻找的答案,但使用Url.Route而不是Url.Action似乎有效:

@Url.RouteUrl("r2")

This generates /Home/Index

这会生成/ Home / Index

Update

更新

Phil Haack recommendeds generating URLs using the route name:

Phil Haack建议使用路由名称生成URL:

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.

这可能看起来像一个大问题,但修复实际上非常简单。使用所有路由的名称,并在生成URL时始终使用路由名称。大多数情况下,让路由选择你想要用来生成URL的路由实际上是让它失去了机会。生成URL时,通常可以确切地知道要链接到哪条路径,因此您也可以按名称指定它。

#3


5  

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:

更新1:

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

我正在挖掘MVC源代码并创建了一些可以重现这个问题的测试。问题似乎是什么时候

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.

运行。它使用旧id创建一个查询字符串。究竟为什么我不能说这个类不在MVC源中。

#4


1  

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.

因为r2没有将id参数定义为URL的一部分?如果您将其更改为{controller} / {action} / {id},则可以。如果将r2更改为不包含操作,您将看到相同的行为:操作也将使用查询变量。

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.

您明确将其设置为“”的事实意味着无论如何路由都会将其考虑在内。只是不添加id,生成链接时你会没事的。