【问题标题】:How to ignore current route values when generating links?生成链接时如何忽略当前路由值?
【发布时间】:2011-09-25 16:35:30
【问题描述】:

这个问题类似于asp.net mvc Html.ActionLink() keeping route value I don't want,但有一个转折使它更复杂。

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

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

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

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

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

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

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

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

前两个是有意义的,并且正在使用第一条路线。

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

谁能解释一下,并建议我如何让它不出现?

【问题讨论】:

  • +1 回答了一个很好的令人费解的问题 :-)
  • @nulltoken: 嘿,你想出了触发它的网站 :)

标签: c# asp.net-mvc asp.net-mvc-routing


【解决方案1】:

我刚刚测试了这个,它似乎工作正常。

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

生成

/Home/Index

【讨论】:

  • 遇到了这个问题,你的解决方案有效,但我仍然得到一个类似的 URL:“/Home/Index?id=" 不是我想要的,但我猜应该足够接近..跨度>
【解决方案2】:

这可能不是您要寻找的答案,但使用 Url.Route 而不是 Url.Action 似乎可行:

@Url.RouteUrl("r2")

这会生成/Home/Index

更新

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

这似乎是个大问题, 但修复实际上非常简单。 为您的所有路线使用名称和 总是使用路由名称 生成 URL。 大多数时候, 让路由整理出哪条路由 你想用来生成一个 URL 是 真的把它留给机会。什么时候 生成一个URL,你一般都知道 您要链接的确切路线 到,所以你不妨指定它 名字。

【讨论】:

  • 感谢丹尼尔,这确实带来了一个可行的解决方案,尽管有点脏。 Mikael 以几分钟的优势击败了你 :)
  • 是的,我见过。当我看到他的答案时,我打算删除我的答案,但后来我想起了 Phil 的帖子,并决定保留它以包含引用,以作为上下文。很高兴帮助:)
  • 关于肮脏...我记得当我第一次阅读菲尔的帖子时认为这是一个肮脏的解决方案。但后来我改变了主意,现在认为使用路线名称实际上是一个好主意。它还为您提供了额外的好处,即能够将控制器和操作重命名/移动到您心中的内容,而不必担心更改所有视图。干杯。
【解决方案3】:

如果你不在乎它是如何解决的,在这种情况下解决它是很容易的。

将第三个链接改为:

@Url.RouteUrl("R2")

这给了我:

  • /Home/Foo/索引
  • /Home/blah/索引
  • /首页/索引

为什么会在第一种情况下发生,我还没有弄清楚。我也被这个咬过,但主要是在表单方面。

更新 1:

我正在挖掘 MVC 源代码并创建了一些重现此问题的测试。问题似乎是当

RouteCollection.GetVirtualPath(requestContext, correctedValues);

正在运行。它使用旧 ID 创建一个查询字符串。究竟为什么我不知道该类不在 MVC 源中。

【讨论】:

  • +1 用于解决方法。但我肯定会对不需要直接涉及路线的方式感兴趣
  • 是的,这似乎确实有效,尽管它有点脏。在实际场景中,我实际上想要执行不同的操作,因此我必须将其显式传递给 RouteUrl,例如新的 { 动作 = "SomeAction" }。但是除非有人想出更好的东西,否则我会在这个上给你打勾:)
  • 令人费解的是,即使它不工作,它已经到达了正确的“R2”路线(我认为)。因此,RouteUrl 似乎有一个副作用,即忽略环境值,这就是它起作用的原因。
  • 删除该值的问题是它可能会影响您之后生成的其他链接
  • 没错,我删除了那个部分,所以没有人使用它,让他们的同事发疯。
【解决方案4】:

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

您明确将其设置为 "" 的事实意味着路由无论如何都会考虑它。只是不要添加id,生成链接时就可以了。

【讨论】:

  • 如果我根本不添加'id',那么上面的情况#1,它会返回错误的东西(使用第一条路线)。
  • 而且我不能在不传递 id 的情况下将 r2 更改为 {controller}/{action}/{id}。除非你的意思是也给它一个默认值?当路线根本不需要它时,用 ID 做任何事情似乎很古怪。我只是想在建立链接时完全清除它。
  • 路由将始终将路由值添加到作为约定生成的 URL(我在构建 MVC SiteMapProvider 时经常诅咒...)。如果您想使用特定路由,请改用路由名称 (Url.RouteUrl),并且不要让路由根据您提供的内容“猜测”路由。我同意这不是你对框架的期望,但改变这种行为可能会导致更多的混乱。
  • 是的,RouteUrl 似乎在这里有所帮助
猜你喜欢
  • 1970-01-01
  • 2019-12-15
  • 1970-01-01
  • 2011-06-30
  • 2014-10-29
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多