MVC 4 catch all route never reached

蹲街弑〆低调 提交于 2019-12-05 20:47:44

问题


When attempting to create a catch all route in MVC 4 (something I've found several examples of, and based my code on) it returns a 404 error. I'm running this on IIS 7.5. This seems like a straight forward solution, so what am I missing?

One note, if I move the "CatchAll" route above the "Default" route it works. But of course then none of the other controllers are ever reached.

Here is the code:

Route.Config:

        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" }
        );

Controller:

public class CatchAllController : Controller
{

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

}

回答1:


Since the ultimate goal of creating the catchall route was to be able to handle dynamic urls and I was unable to find a direct answer to the original issue above, I approached my research from a different perspective. In doing so I came across this blog post: Custom 404 when no route matches

This solution allows handling of multiple sections within a given url (i.e. www.mysite.com/this/is/a/dynamic/route)

Here is the final custom controller code:

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;
 }



回答2:


It's probably because whatever route your're testing this with is matching your 1st - Default route. The way the routing in MVC works, any address you pass in will try to match routes in your routes collection in order of appearance. Once it find the 1st matching route it aborts further execution. In this case your Default route is 1st one in the list so if it is matched your second route will never be examined.

Basically write something like http://www.mysite.com/Home/Testing/Item/Page in your address bar and this should fail to match to your Default route and then try to match the CatchAll route.




回答3:


Try defining the optional string dynamicRoute parameter on your route:

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


来源:https://stackoverflow.com/questions/16527740/mvc-4-catch-all-route-never-reached

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!