8

当尝试在 MVC 4 中创建一个 catch all 路由时(我已经找到了几个示例,并且基于我的代码),它返回一个 404 错误。我在 IIS 7.5 上运行它。这似乎是一个直接的解决方案,所以我错过了什么?

请注意,如果我将“CatchAll”路线移动到“默认”路线上方,它会起作用。但是当然,其他控制器都没有到达。

这是代码:

路线配置:

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        routes.MapRoute(
            "CatchAll",
            "{*dynamicRoute}",
            new { controller = "CatchAll", action = "ChoosePage" }
        );

控制器:

public class CatchAllController : Controller
{

    public ActionResult ChoosePage(string dynamicRoute)
    {
        ViewBag.Path = dynamicRoute;
        return View();
    }

}
4

3 回答 3

9

由于创建包罗万象的路线的最终目标是能够处理动态网址,而我无法找到上述原始问题的直接答案,因此我从不同的角度进行了研究。在这样做时,我遇到了这篇博文:没有路由匹配时的自定义 404

此解决方案允许处理给定 url 中的多个部分(即 www.mysite.com/this/is/a/dynamic/route)

这是最终的自定义控制器代码:

public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
 {
     if (requestContext == null)
     {
         throw new ArgumentNullException("requestContext");
     }

     if (String.IsNullOrEmpty(controllerName))
     {
         throw new ArgumentException("MissingControllerName");
     }

     var controllerType = GetControllerType(requestContext, controllerName);

     // This is where a 404 is normally returned
     // Replaced with route to catchall controller
     if (controllerType == null)
     {
        // Build the dynamic route variable with all segments
        var dynamicRoute = string.Join("/", requestContext.RouteData.Values.Values);

        // Route to the Catchall controller
        controllerName = "CatchAll";
        controllerType = GetControllerType(requestContext, controllerName);
        requestContext.RouteData.Values["Controller"] = controllerName;
        requestContext.RouteData.Values["action"] = "ChoosePage";
        requestContext.RouteData.Values["dynamicRoute"] = dynamicRoute;
     }

     IController controller = GetControllerInstance(requestContext, controllerType);
     return controller;
 }
于 2013-05-14T13:10:41.663 回答
4

这可能是因为您正在测试的任何路线都与您的第一条默认路线相匹配。MVC 中路由的工作方式,您传入的任何地址都将尝试按照出现的顺序匹配您的路由集合中的路由。一旦找到第一个匹配的路由,它就会中止进一步的执行。在这种情况下,您的默认路由是列表中的第一个,因此如果匹配,您的第二个路由将永远不会被检查。

基本上在地址栏中写http://www.mysite.com/Home/Testing/Item/Page之类的东西,这应该无法匹配到您的默认路由,然后尝试匹配 CatchAll 路由。

于 2013-05-13T17:41:03.547 回答
0

尝试在您的路线上定义可选的字符串 dynamicRoute 参数:

 routes.MapRoute( 
      "CatchAll", 
      "{*dynamicRoute}", 
      new { controller = "CatchAll", action = "ChoosePage", dynamicRoute = UrlParameter.Optional } );
于 2013-05-13T17:59:15.913 回答