使用和不使用查询字符串路由旧请求

Die*_*hon 6 asp.net-mvc-routing asp.net-mvc-3

(开始之前:我知道这个这个.我想找到一个更简洁的解决方案 - 如果可能的话 - 稍微更具体的问题)

我正在重写MVC中的旧Webforms应用程序.像往常一样,不应该破坏永久链接.

我正在使用标准{controller}/{action}/{id}路线.传统路径通常是SomePage.aspx?ID=xxx,我有一个特殊情况,其中Foo.aspxBar(新URL:/ Bar/ Bar/Index)的列表,并且 Foo.aspx?ID=xxxBar详细信息(新URL:/ Bar/View/xxx)

一种可能的解决方法是在默认值之前添加以下内容MapRoute:

routes.MapRoute("Bar View", "Foo.aspx",
                new { controller = "Bar", action = "View" });
Run Code Online (Sandbox Code Playgroud)

然后在BarController中定义相应的操作:

public ActionResult View(int? id)
{
    if (id == null)
        return RedirectToAction("Index");
    return View();
}
Run Code Online (Sandbox Code Playgroud)

这有两个问题:

  • 现在,如果我创建一个ActionLink,它将使用旧格式
  • 我想在路线上处理这件事; 使id可以为空并在控制器中重定向是错误的

我可以手动映射遗留URL(我不需要通用解决方案,只有大约8页)

这是一个新项目,所以我没有任何关系.

Die*_*hon 3

我能够根据Dangerous 的想法以及基于此答案的约束来解决这个问题。

我的新路由表是:

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", /*...*/);
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)