【问题标题】:MVC URL.RouteUrl removes RouteValues but URL.Action preserves them?MVC URL.RouteUrl 删除 RouteValues 但 URL.Action 保留它们?
【发布时间】:2011-10-17 04:05:09
【问题描述】:

假设我们有这条路线:

routes.MapRoute(
"Library",
"Lib/{id}/{lang}",
New With {.controller = "MyLibrary", .action = "ShowItem", .id= 0, .lang = "en"}
)

假设我们请求这个 url

http://localhost/Lib/10/de

所以现在我们有了这个路由值id = 10 & lang = de

问题出在这里:

这段代码:

<%= Url.Action("ShowItem", New With {.id = 45})%>

返回:

http://localhost/Lib/45/de

它改变了 id 但保留了 lang

但是这段代码:

<%= Url.RouteUrl("Library", New With {.id = 45})%>

返回:

http://localhost/Lib/45

它改变了 id 但删除了 lang

这是一个错误还是什么?我知道如何解决这个问题,但是这种不同的行为非常令人困惑。我对吗?或者只是想象一下?

一个快速的解决方法是:

<%= Url.RouteUrl("Library", New With {.id = 45},.lang = RouteData.Values("lang"))%>

【问题讨论】:

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


    【解决方案1】:

    好的,所以理论上正确的预期 mvc 行为是,如果它们出现在您指定的后面的段中,它不应该重用当前请求中的变量。所以我想知道你是否有一些其他路线定义为你所描述的不太正确,所以它是否可以匹配其他路线。如果不是,那可能是一个错误。

    无论如何,因为上述行为(当它工作时!)非常令人困惑,最佳实践是在创建链接时提供所有段变量,如上所述使用 UrlParameter.Optional。那么您就不必担心这种模棱两可了。

    对于它的价值,您看到的第二个结果(即 RouteUrl)是正确的行为。 Action 的行为应该相同。

    【讨论】:

    • 感谢 DanH 的回答,很抱歉我回复晚了。正如你所说,我认为这是因为其他路线。在大卫的回答和建议之后,我创建了一个新项目,发现一切正常。我真的很想给你一部分赏金,但大卫的回答看起来更好。再次感谢并 +1
    • 我要给 David 赏金积分,给 Dan 答案。你们俩都帮了我很多。大卫的回答很完整,我发现问题出在定义的路线上。丹的回答确保其他定义的路线导致了这个问题。
    【解决方案2】:

    这个和How to ignore current route values when generating links?基本一样。

    试试这样的:

    <%= Url.Action("ShowItem", New With {.id = 45, .lang=UrlParameter.Optional})%>
    

    抱歉,我对 VB 语法不太熟悉,所以它可能不是 100% 正确,但关键是要传递 UrlParameter.Optional,这样它就不会保留路由值。

    更新:我应该补充一点,你得到的行为不是预期的。从一个新的 MVC 应用程序中,我添加了一个带有 ShowItem 操作的基本 MyLibrary 控制器,使用以下代码(抱歉,它是 C#):

    @Url.Action("ShowItem", new {id = 45})<br />
    @Url.RouteUrl("Library", new {id = 45})<br />
    @Url.Action("ShowItem", new {lang = "fr"})<br />
    @Url.RouteUrl("Library", new { lang = "fr" })<br />
    

    当我转到 /Lib/10/de 时,它​​会显示:

    /Lib/45
    /Lib/45
    /Lib/10/fr
    /Lib/10/fr
    

    所以请注意:

    • 这两种方法没有区别
    • 只有在 URL 中之前没有更改值的情况下才会保留当前路由值。因此保留了“10”,但没有保留“de”。

    我不知道您为什么会看到不同的东西,但我建议从干净的应用程序中进行测试,以与您的应用程序中可能发生的其他事情隔离开来。

    【讨论】:

    • 好吧,我的问题是:为什么这两种方法中有两种不同的行为?顺便说一句,在我的项目中,正如您所说,使用:UrlParameter.Optional 定义了我想要的路由,并且它是相同的行为。
    • 我说的是将 UrlParameter.Optional 传递给 Url.Action,而不是在设置路由时。这是完全不同的事情。
    • 我会尽快尝试并对此发表评论。但正如我所说,问题在于这两种类似方法之间的不同行为。并 +1 在此线程中发帖和 cmets。
    • 抱歉回复晚了。正如您建议的那样,我开始了一个干净的项目,并且一切正常,所以我怀疑问题出在定义的其他路线上。您应该得到赏金来评论和更新您的答案。再次感谢你强迫我在一个干净的应用程序中测试它:)
    • 我要给大卫赏金积分,给丹丹答案。你们俩都帮了我很多。大卫的回答很完整,我发现问题出在定义的路线上。丹的回答确保其他定义的路线导致了这个问题。
    【解决方案3】:

    看起来这是预期的操作。 http://msdn.microsoft.com/en-us/library/dd492912.aspx 表示“为指定的操作名称和路由值生成操作方法的完全限定 URL。”这意味着它将使用路由值填充其他字段?

    只是猜测......

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-30
    • 2020-10-20
    • 2020-03-07
    • 2010-09-14
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多