生成链接时如何忽略当前路由值?
这个问题类似于asp.net mvc Html.ActionLink(),它保留了我不想要的路由值 ,但有一个扭曲使得它更复杂。
从默认的新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个生成的链接。 我明白了
- “/首页/美孚/索引”
- “/首页/胡说/索引”
- “/首页/指数?ID =富”
前两个是有道理的,并且正在使用第一条路线。
但是在第三个链接中,遇到第二个路径,我不明白为什么id = Foo在查询字符串上传递,因为我明确地传递了一个空id。 我希望它只是生成“/ Home / Index”。
任何人都可以解释这一点,并建议我如何让它不显示?
我只是测试了它,似乎工作正常。
Url.Action("Index", new { id = UrlParameter.Optional })
生成
/Home/Index
在这种情况下解决它很容易,如果你不关心它是如何解决的。
将第三个链接更改为:
@Url.RouteUrl("R2")
这给了我:
- /主页/美孚/索引
- /首页/胡说/索引
- /首页/索引
为什么它在第一种情况下发生是我尚未弄清楚的。 我也被这种方式所困扰,但主要是在forms方面。
更新1:
我正在挖掘MVC源代码并创建了一些可以重现这个问题的测试。 问题似乎是什么时候
RouteCollection.GetVirtualPath(requestContext, correctedValues);
运行。 它使用旧id创建一个查询字符串。 究竟为什么我不能说这个类不在MVC源中。
这可能不是您正在寻找的答案,但使用Url.Route而不是Url.Action似乎有效:
@Url.RouteUrl("r2")
这会生成/Home/Index
更新
Phil Haack建议使用路由名称生成URL:
这可能看起来像一个大问题,但修复实际上非常简单。 使用所有路由的名称,并在生成URL时始终使用路由名称。 大多数情况下,让路由选择你想要用来生成URL的路由实际上是让它失去了机会。 生成URL时,通常可以确切地知道要链接到哪条路径,因此您也可以按名称指定它。
因为r2没有将id参数定义为URL的一部分? 如果您将其更改为{controller} / {action} / {id},则可以。 如果将r2更改为不包含操作,您将看到相同的行为:操作也将使用查询变量。
您明确将其设置为“”的事实意味着无论如何路由都会将其考虑在内。 只是不添加id,生成链接时你会没事的。