假设您有一个在购物车中显示产品的操作方法
// ProductsController.cs
public ActionMethod Index(string gender) {
// get all products for the gender
}
在其他地方,在您Url.RouteUrl
用来创建指向站点上其他页面的 HREF 链接的每个页面上显示的标头中:
<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a>
这testimonials-route
是global.ascx
由下面的第一条路线定义的。请注意,上面的调用RouteUrl
不提供 a 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
,我们会得到一个 HREF。/testimonials/women
如果有人访问该页面/products
,那么我们会得到一个空的 HREF(对 RouteUrl 的调用返回 null)。
但这没有意义不是吗?如果我们不为它提供路由值,testimonials-route
应该默认为我们?'neutral'
事实证明,Url.RouteUrl(routeName, routeValues)
辅助扩展将首先在其routeValues
参数中查找gender
路由值,如果在该字典中找不到它,它将查看我们所在的当前 URL(请记住,Url 是 UrlHelper 对象它具有可用的当前请求的上下文)。
如果我们在男士产品页面上,这可能会给我们一个男士推荐的链接,但如果我们没有在RouteUrl
调用中传递值并明确指定“中性”,这可能不是我们想要的文件中的默认值global.asax.cs
。
在我们访问的情况下,/products/
我们触发了'products-route'
路由并Products(null)
调用了该方法。当Url.RouteUrl()
我们gender
使用testimonials-route
. 即使我们为gender
in 'testimionials-route
' 指定了默认值,它仍然使用这个 null 值,这会导致路由失败并RouteUrl
返回 null。[注意:路由失败是因为我们对 (men|women|neutral) 有限制,而 null 不适合]
它实际上变得更可怕 - 因为“控制器”和“动作”可以以相同的方式继承。即使使用具有默认控制器的显式路由名称调用 RouteUrl(...),这也可能导致生成完全错误的控制器的 URL。
在这种情况下,一旦您弄清楚了,您可以通过多种方式轻松修复它,但在其他情况下可能会导致一些危险行为。这可能是设计使然,但它绝对是可怕的。