ASP.NET MVC 2 RC2路由 - 如何在使用ActionLink引用更高级别时清除低级别值?

时间:2010-03-23 15:10:40

标签: asp.net-mvc asp.net-mvc-2 routing asp.net-mvc-routing

[注意:我正在使用ASP.NET MVC2 RC2。]

我有这样的网址:

  

/客户/ 123 /命令/ 456 /项目/索引

     

/客户/ 123 /命令/ 456 /项目/ 789 /编辑

我的路由表首先列出了最具体的路由,所以我得到了:

// customers/123/orders/456/items/789/edit
routes.MapRoute(
    "item", // Route name
    "customers/{customerId}/orders/{orderId}/items/{itemId}/{action}", // URL with parameters
    new { controller = "Items", action = "Details" }, // Parameter defaults
    new { customerId = @"\d+", orderId = @"\d+", itemId = @"\d+" } // Constraints
);

// customers/123/orders/456/items/index
routes.MapRoute(
    "items", // Route name
    "customers/{customerId}/orders/{orderId}/items/{action}", // URL with parameters
    new { controller = "Items", action = "Index" }, // Parameter defaults
    new { customerId = @"\d+", orderId = @"\d+" } // Constraints
);

当我进入“编辑”页面时,我想要一个链接备份到“索引”页面。所以,我用:

ActionLink("Back to Index", "index")

但是,由于存在环境项ID,因此会产生URL:

  

/客户/ 123 /命令/ 456 /项目/ 789 /索引

...而我希望它“忘记”商品ID并使用:

  

/客户/ 123 /命令/ 456 /项目/索引

我已尝试覆盖项目ID,如下所示:

ActionLink("Back to Index", "index", new { itemId=string.empty })

......但这不太奏效。给我的是:

  

/客户/ 123 /命令/ 456 /物品?的itemId = 789

如何说服ActionLink“忘记”商品ID?


编辑:修正问题 - 我指的是“订单”,我指的是“商品”。

编辑:详细说明了为什么itemId = string.empty不起作用。

4 个答案:

答案 0 :(得分:2)

在约束中,您可以删除任何不需要的routeValues。

values.Remove("itemId");

然后创建一个继承自IRouteConstraint的类。

然后在Match方法中清除您的路由值并返回true(表示路由匹配)。

public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{

    values.Remove("itemId");    
    return true;
}

然后在Global.asax.cs中更改

new { customerId = @"\d+", orderId = @"\d+" }

new { customerId = @"\d+", orderId = @"\d+", custom=new MyNewConstraint() }

答案 1 :(得分:1)

我删除了我以前的答案,没有注意到他们是同一个控制器。尝试设置itemId = string.empty。这将使第一条路线失败,因为它需要该位置的数字。

ActionLink("Back to Index", "index", new { itemId=string.empty })

您可以选择手动创建一个包含路径“item”名称的链接

<%= Url.RouteUrl("item", new { controller="Items", action="Index", orderId=3 ... }) %>

答案 2 :(得分:1)

好吧,我认为通过使用RouteLink代替ActionLink,我可以做到我想做的事情:

RouteLink("Back to Index", "items", new { action="index" })

...其中第二个参数是我想要显式调用的路由的名称。


编辑:我真的不想通过我所有的ActionLinks并将它们放在这个表单中,所以我修改了“项目”规则以包含对{action}参数的约束,以使“index”与此路由不匹配。因此,它匹配“items”路由 - 它没有itemId参数。这似乎是一种更简单的方法,因为我的大部分代码都没有改变。

答案 3 :(得分:1)

问题根源的解决方案

似乎最佳解决方案(没有像解决方法一样的味道)是解决问题的方法,它解决了它的根源和路由问题。

我编写了一个名为Route的自定义RouteWithExclusions类,它可以定义在生成网址时应排除/删除的路由值名称。

整个问题在my blog post中详细说明并解释,所有代码也在那里提供。检查一下,它可以帮助您在不使用约束的情况下解决此路由问题,但可以使用满足要求的路由。

相关问题