MVC的URL.RouteUrl删除了RouteValues,但去掉了URL.行动保护它们

本文关键字:URL 掉了 保护 RouteUrl 删除 MVC RouteValues | 更新日期: 2023-09-27 18:11:20

假设我们有这样的路由:

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 但保留

但是这个代码:

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

的回报:

http://localhost/Lib/45

它改变了id但删除了lang!

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

一个快速的修复方法是:

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

MVC的URL.RouteUrl删除了RouteValues,但去掉了URL.行动保护它们

好的,所以理论上正确的预期mvc行为在这里是,它不应该重用当前请求的变量,如果他们发生在一个较晚的段比你指定的。所以我想知道你是否有一些其他的路线被定义为你所描述的不是很正确,所以它会匹配其他的东西吗。如果不是,可能是bug。

不管怎样,因为上面的行为(当它工作的时候!)是相当混乱的,最佳实践是在创建链接时使用UrlParameter提供所有的段变量。如上所述是可选的。那么你就不用担心这种歧义了。

无论如何,你看到的第二个结果(即RouteUrl)是正确的行为。

这与如何在生成链接时忽略当前路由值基本相同。

试试这样写:

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

对不起,我不太熟悉VB语法,所以它可能不是100%正确,但关键是传递UrlParameter。可选,因此不保留路由值。

Update:我应该补充一下,您得到的行为是意料之外的。从一个新的MVC应用程序,我添加了一个基本的MyLibrary控制器与ShowItem动作,与此代码(对不起,它是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'没有。

我不知道为什么你看到一些不同的东西,但我建议从一个干净的应用程序测试,从其他事情可能会发生在你的应用程序。

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