假设您有一个操作方法来在购物车中显示产品
// ProductsController.cs
public ActionMethod Index(string gender) {
// get all products for the gender
}
在其他地方,在每个页面上显示的 header 中,您使用 Url.RouteUrl
创建指向网站上其他页面的 HREF 链接:
<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a>
此testimonials-route
由下面的第一条路由在global.ascx
中定义。
请注意,上面对 RouteUrl
的调用不提供 gender
,但路由定义为默认值“neutral”,因此我们期望 Testimonials.Index("neutral"") 被调用。
routes.MapRoute(
"testimonials-route",
"testimonials/{gender}",
new { controller = "Testimonials", action = "Index", gender = "neutral" },
new { gender = "(men|women|neutral)" }
);
routes.MapRoute(
"products-route",
"products/{gender}",
new { controller = "Products", action = "Index", gender = (string)null },
new { gender = "(men|women|neutral)" }
);
如果有人访问页面 /products/women
,我们会收到 /testimonials/women
的 HREF
如果有人访问页面 /products
那么我们会得到一个空的 HREF(对 RouteUrl 的调用返回 null)。
但这没有意义,不是吗?如果我们不为其提供路由值,那么 testimonials-route
应该默认为 'neutral'
吗?
事实证明,Url.RouteUrl(routeName, routeValues)
辅助扩展程序将首先在其 routeValues
参数中查找 gender
路由值,如果在该字典中找不到它,它将查看我们所在的当前 URL(请记住,Url 是一个 UrlHelper 对象,它具有可用的当前请求的上下文)。
如果我们在男士产品页面上,这可能会给我们一个男士推荐的链接,但如果我们没有在 RouteUrl 中传递值,这可能不是我们想要的效果
code> 调用,并在 global.asax.cs
文件中显式指定“中性”作为默认值。
在我们访问 /products/
的情况下,我们触发了 'products-route'
路由,并且 Products(null)
方法是叫。当我们使用 testimonials-route
创建 URL 时,对 Url.RouteUrl()
的调用实际上继承了 gender
的这个 null 值。即使我们在 'testimionials-route
' 中指定了 gender
的默认值,它仍然使用这个 null 值,这会导致路由失败,并且 RouteUrl
返回空值。 [注意:路线失败是因为我们对 (men|women|neutral) 有限制,而 null 不适合]
它实际上变得更可怕 - 因为“ Controller ”和“ Action ”可以以相同的方式继承。即使使用具有默认 Controller 的显式路由名称调用 RouteUrl(...),这也可能导致生成完全错误的 Controller 的 URL。
在这种情况下,一旦你弄清楚了它,你就可以通过多种方式轻松修复它,但在其他情况下它可能会导致一些危险的行为。这可能是设计使然,但这绝对是可怕的。
最佳答案
我的解决方案是这样的:
HtmlExtension 辅助方法:
public static string RouteUrl(this UrlHelper urlHelper, string routeName, object routeValues, bool inheritRouteParams)
{
if (inheritRouteParams)
{
// call standard method
return urlHelper.RouteUrl(routeName, routeValues);
}
else
{
// replace urlhelper with a new one that has no inherited route data
urlHelper = new UrlHelper(new RequestContext(urlHelper.RequestContext.HttpContext, new RouteData()));
return urlHelper.RouteUrl(routeName, routeValues);
}
}
我现在可以做:
Url.RouteUrl('testimonials-route', new { }, false)
并确信无论上下文如何,它的行为方式始终相同。
它的工作方式是采用现有的 UrlHelper
并创建一个带有空白“RouteData”的新 UrlHelper。这意味着没有任何东西可以继承(甚至是空值)。
关于asp.net-mvc-routing - 如何防止 Url.RouteUrl(...) 继承当前请求的路由值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1148443/