使用和不使用查询字符串路由遗留请求
Posted
技术标签:
【中文标题】使用和不使用查询字符串路由遗留请求【英文标题】:Routing legacy requests with and without querystring 【发布时间】:2012-02-28 02:15:25 【问题描述】:(开始之前:我知道this 和this。如果可能的话,我想为稍微更具体的问题找到一个更简洁的解决方案)
我正在用 MVC 重写一个旧的 Webforms 应用程序。像往常一样,不应破坏任何永久链接。
我正在使用标准的controller/action/id
路由。旧路径通常是SomePage.aspx?ID=xxx
,我有一个特殊情况,Foo.aspx
是Bar
的列表(新 URL:/Bar 或 /Bar/Index ) 和
Foo.aspx?ID=xxx
是 Bar
详细信息(新 URL:/Bar/View/xxx)
一种可能的解决方法是在默认 MapRoute
之前添加以下内容:
routes.MapRoute("Bar View", "Foo.aspx",
new controller = "Bar", action = "View" );
然后在BarController中定义相应的动作:
public ActionResult View(int? id)
if (id == null)
return RedirectToAction("Index");
return View();
这样做有两个问题:
现在,如果我创建 ActionLink,它将使用旧格式 我想在路由中处理这个问题;使 id 可以为空并在控制器中重定向是错误的我可以手动映射旧版 URL(我不需要通用解决方案,只有大约 8 页)
这是一个新项目,所以我不依赖任何东西。
【问题讨论】:
【参考方案1】:我相信如果您指定以下路线:
routes.MapRoute(
null,
"Bar/action/id",
new controller = "Bar", action = "View", id = UrlParameter.Optional ,
new action = "Index|Next" //contrain route from being used by other action (if required)
);
routes.MapRoute(
null,
"Foo.aspx/id",
new controller = "Bar", action = "View", id = UrlParameter.Optional
);
//specify other routes here for the other legacy routes you have.
那么这应该可以解决您的第一个问题。如果用户在 url 中指定 Foo.aspx,那么他们将被带到 View 操作。
如果动作链接:
@html.ActionLink("Click me", "Index", "Bar")
指定,然后将使用第一条路线(因为顺序很重要)。
但是,我不知道如何指定如果Foo.aspx?id=...
然后转到一条路线,否则如果指定Foo.aspx
然后转到另一条路线。因此,我会检查 id 在操作中是否为空。但是,如果你真的发现了这一点,我非常想知道。
希望这会有所帮助。
【讨论】:
【参考方案2】:我能够基于Dangerous' idea 加上基于this answer 的约束来解决这个问题。
我的新路由表是:
routes.MapRoute("Bar", "Bar/action/id",
new
controller = "Bar",
action = "Index",
id = UrlParameter.Optional
);
routes.MapRoute("Bar View", "Foo.aspx",
new controller = "Bar", action = "View",
new id = new QueryStringConstraint());
routes.MapRoute("Bar Index", "Foo.aspx",
new controller = "Bar", action = "Index" );
routes.MapRoute("Default", /*...*/);
QueryStringConstraint 再简单不过了:
public class QueryStringConstraint : IRouteConstraint
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
return httpContext.Request.QueryString.AllKeys
.Contains(parameterName, StringComparer.InvariantCultureIgnoreCase);
【讨论】:
Diego 很好的答案,但你不知道如何拒绝网址“Bar/View/3”而不是“Bar/View?id=3”? @DenisAgarev 我不明白你的问题。 抱歉不清楚,我在问题上犯了错误)))我的意思是有一种方法只允许查询字符串 URL 像“Bar/View?id=3”,因为在你的解决方案 URL 中像“酒吧/视图/任何东西”也将被允许用于相同的路线。 一切皆有可能。但这将是一个不同的问题以上是关于使用和不使用查询字符串路由遗留请求的主要内容,如果未能解决你的问题,请参考以下文章
如何在我的所有请求查询字符串中包含 JSON webtoken