Search code examples
asp.net-mvcasp.net-mvc-routinghttp-status-code-404catch-all

MVC 4 catch all route never reached


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

}

Solution

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