因此,我已经尝试了几个小时来解决理论上应该非常简单的问题。让我们来看看这个示例网址:
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 });
(注意,这是一个简化的示例;控制器名称和操作方法名称等“必需”路由片段将分别由通用参数和表达式检查确定)。
这实际上执行了重定向,但是,来自当前请求的路由值被附加到重定向上,因此您进入重定向循环(请注意,我没有在路由对象中包含城市路由值)。如何阻止“城市”路线值包含在此重定向中?
我尝试了以下方法来摆脱路由值:
- 编写我自己的
RouteValueDictionary
/匿名路由数据对象并将其传递给RedirectToRoute
. - 创建我自己的操作结果来自己检查
RouteTable.Routes
和查找路线,并自己更换令牌。这似乎是最“笨拙”的,并且似乎是在重新发明轮子。 - 制作一个这样的方法
RedirectWithout
需要一个键值并调用RedirectToRouteResult.RouteValues.Remove(key)
- 这也不起作用。 - 我还尝试为我不想添加的键添加空值;然而,这会改变路由到不正确的地方——即
new { controller = "Products", action = "List", state = stateName, city = (string)null }
发出一个重定向到/Products/List?state=Texas
的不是正确的 URL。
这一切似乎都源于 RedirectToRoute 采用当前请求上下文来构造虚拟路径数据。有解决方法吗?