在重定向上删除路由值

时间:2012-08-01 20:03:41

标签: c# asp.net-mvc asp.net-mvc-routing

所以,我现在已经尝试了几个小时来解决理论上应该非常简单的事情。我们来看看这个示例网址:

http://sample.com/products/in/texas/dallas

这映射到特定路线:

routes.MapRoute(
    "products",
    "products/in/{state}/{city}",
    new { controller = "Products", action = "List", state = UrlParameter.Optional, city = UrlParameter.Optional });

在我的行动方法中,我可以进行查找,以确保“德克萨斯”和“达拉斯”存在,并且“达拉斯”存在于德克萨斯州内。这一切都很好,花花公子。但是,在城市不存在的情况下(无论是因为地理位置不正确还是错误),我希望它能够支持州级别。例如:

http://sample.com/products/in/texas/dallax

那应该发布重定向到

http://sample.com/products/in/texas

执行此操作的“简单”方法是简单地发出类似的重定向调用:

return Redirect("/products/in/" + stateName);

但是,我正在尝试将其与URL结构分离;例如,如果我们决定改变路径的外观(比如,将模式更改为products/around/{state}/{city}),那么我必须知道我需要对此控制器进行更新以修复URL重定向。

如果我可以制定一个只检查路线值并且可以解决问题的解决方案,那么我不必担心如果我改变路线模式,因为路线值仍然可以计算出来。

理想情况下,我本来希望做这样的事情:

return RedirectToRoute(new { controller = "Products", action = "List", state = state });

(注意,这是一个简化的例子;控制器名称和操作方法名称之类的“必需”路径部分将分别由Generic argument和Expression inspection确定)。

实际上执行重定向, HOWEVER ,来自当前请求的路由值被附加到重定向上,因此您进入重定向循环(请注意,我没有包含城市路由值在路线对象中)。 如何阻止“城市”路线值包含在此重定向中?

我尝试了以下方法来摆脱路线值:

  1. 撰写我自己的RouteValueDictionary /匿名路由数据对象,并将其传递给RedirectToRoute的重载。
  2. 创建我自己的行动结果以检查RouteTable.Routes并自行查找路线,并自行更换令牌。这似乎是最“kludgy”,似乎是重新发明轮子。
  3. 制作一个类似RedirectWithout的方法,它接受一个键值并调用RedirectToRouteResult.RouteValues.Remove(key) - 这也没有用。
  4. 我还试图为我不想添加的键添加空值;但是,这会将路由更改为不正确的内容 - 即new { controller = "Products", action = "List", state = stateName, city = (string)null }/Products/List?state=Texas发出重定向,这不是正确的URL。
  5. 这一切似乎源于RedirectToRoute采用当前请求上下文来构造虚拟路径数据。有解决方法吗?

1 个答案:

答案 0 :(得分:1)

如果您使用的是T4MVC,您应该能够做到这样的事情:

return RedirectToAction(MVC.Products.List(state, null));

你试过这个吗?

return RedirectToRoute(new 
{
    controller = "Products", 
    action = "List", 
    state = state,
    city = null, 
});

回复评论

也许MVC很困惑,因为你的可选参数不在最后。以下内容适用于指定RedirectToRoute的上述city = null

routes.MapRoute(
    "products",
    "products/in/{state}/{city}",
    new
    {
        controller = "Products",
        action = "List",
        // state = UrlParameter.Optional, // only let the last parameter be optional
        city = UrlParameter.Optional 
    });

然后,您可以添加另一条路线来处理state可选的网址:

routes.MapRoute(null, // I never name my routes
    "products/in/{state}",
    new
    {
        controller = "Products",
        action = "List",
        state = UrlParameter.Optional 
    });