1

因此,我已经尝试了几个小时来解决理论上应该非常简单的问题。让我们来看看这个示例网址:

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 });

在我的操作方法中,我可以进行查找以确保“texas”和“dallas”存在,并且“dallas”存在于德克萨斯州。这一切都很好,花花公子。但是,在城市不存在的情况下(因为地理不正确或拼写错误),我希望它备份州级。例子:

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

那应该发出重定向到

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

执行此操作的“简单”方法是简单地发出 Redirect 调用,如下所示:

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

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

如果我可以制定一个解决方案,只检查路由值并找出问题所在,那么我不必担心更改路由模式,因为仍然可以找出路由值。

理想情况下,我想做这样的事情:

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

(注意,这是一个简化的示例;控制器名称和操作方法名称等“必需”路由片段将分别由通用参数和表达式检查确定)。

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

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

  1. 编写我自己的RouteValueDictionary/匿名路由数据对象并将其传递给RedirectToRoute.
  2. 创建我自己的操作结果来自己检查RouteTable.Routes和查找路线,并自己更换令牌。这似乎是最“笨拙”的,并且似乎是在重新发明轮子。
  3. 制作一个这样的方法RedirectWithout需要一个键值并调用RedirectToRouteResult.RouteValues.Remove(key)- 这也不起作用。
  4. 我还尝试为我不想添加的键添加空值;然而,这会改变路由到不正确的地方——即new { controller = "Products", action = "List", state = stateName, city = (string)null }发出一个重定向到/Products/List?state=Texas的不是正确的 URL。

这一切似乎都源于 RedirectToRoute 采用当前请求上下文来构造虚拟路径数据。有解决方法吗?

4

1 回答 1

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 
    });

然后,您可以添加另一个路由来处理 URL 的 wherestate是可选的:

routes.MapRoute(null, // I never name my routes
    "products/in/{state}",
    new
    {
        controller = "Products",
        action = "List",
        state = UrlParameter.Optional 
    });
于 2012-08-01T20:11:24.420 回答