asp.net-mvc-routing – 如何防止Url.RouteUrl(…)从当前请求继承路由值

前端之家收集整理的这篇文章主要介绍了asp.net-mvc-routing – 如何防止Url.RouteUrl(…)从当前请求继承路由值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设您有一个操作方法在购物车中显示产品
// 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的调用不提供性别,但是路由被定义为默认的“中性”,因此我们期望调用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",gender = (string)null },new { gender = "(men|women|neutral)" }
 );

如果有人访问的页面/产品/女性,我们得到一个HREF / /个人鉴定/妇女
如果有人访问页面/产品,那么我们获得一个空的HREF(对RouteUrl的调用返回null)。

但这没有意义吗? testimonials-route如果我们不为它提供路由值,它应该默认为“中性”?

发生的是Url.RouteUrl(routeName,routeValues)辅助扩展将首先查看其routeValues参数的性别路由值,如果它没有找到它在该字典中,它将查看当前的URL,我们’ (记住Url是一个UrlHelper对象,它具有当前请求的上下文可用)。

如果我们在男士产品页面上,这可能会给我们一个链接到男士的推荐,这可能是一个很好的效果,但是如果我们没有在RouteUrl调用中传递一个值,并明确指定“中性”作为global.asax.cs文件中的默认值。

在我们访问/ products /我们触发了“products-route”路由并调用了Products(null)方法的情况下。当我们使用testimonials-route创建一个URL时,对Url.RouteUrl()的调用实际上继承了这个性别的空值。即使我们在’testimionials-route’中指定了性别的默认值,它仍然使用这个空值,导致路由失败,RouteUrl返回null。 [注意:路由失败,因为我们有一个约束(男|女|中性),null不适合]

它实际上变得更可怕 – “控制器”和“行动”可以以同样的方式继承。这可能导致URL生成完全错误的控制器,即使调用RouteUrl(…)与显式路由名称具有默认控制器。

在这种情况下,一旦你弄清楚了,你可以很容易地解决它在许多方面,但在其他情况下可能会导致一些危险的行为。这可能是设计,但它绝对可怕。

解决方法

我的解决方案是:

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”的新的。这意味着没有什么可以继承(甚至是null值)。

猜你在找的asp.Net相关文章