所以,我现在已经尝试了几个小时来解决理论上应该非常简单的事情。我们来看看这个示例网址:
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 ,来自当前请求的路由值被附加到重定向上,因此您进入重定向循环(请注意,我没有包含城市路由值在路线对象中)。 如何阻止“城市”路线值包含在此重定向中?
我尝试了以下方法来摆脱路线值:
RouteValueDictionary
/匿名路由数据对象,并将其传递给RedirectToRoute
的重载。 RouteTable.Routes
并自行查找路线,并自行更换令牌。这似乎是最“kludgy”,似乎是重新发明轮子。 RedirectWithout
的方法,它接受一个键值并调用RedirectToRouteResult.RouteValues.Remove(key)
- 这也没有用。 new { controller = "Products", action = "List", state = stateName, city = (string)null }
向/Products/List?state=Texas
发出重定向,这不是正确的URL。 这一切似乎源于RedirectToRoute采用当前请求上下文来构造虚拟路径数据。有解决方法吗?
答案 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
});