Jeff Keslinke
Jeff Keslinke

Reputation: 4358

.Net MVC Routing Catchall not working

I can't seem to figure this out. I'm experimenting with MVC Beta and am trying to implement a catchall route such that if the user enters mysite.com/blah instead of mysite.com/home/index it will hit the "Error" route.

Unfortunately it seems that the "Default" route always catches "blah" first. In fact the only route I've been able to get to the "Error" route with is blah/blah/blah/blah.

Is this the way it's supposed to work, because I've seen other examples that have the "Default" and "Error" route set up just like this and it seems that if they were to type in a controller that doesn't exist it would hit the "Error" route.

Is there something I'm missing (very possible) or will I just have to create a specific route for each controller?

Code I'm using:

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

        routes.MapRoute(
            "Error",
            "{*catchall}",
            new { controller = "Base", action = "Error", id = "404" }
        );

Thank you, Jeff

Upvotes: 16

Views: 7841

Answers (4)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038770

In order to handle errors I used the Application_Error event in one of my projects:

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "HttpError500");

            if (httpException.GetHttpCode() == 404)
            {
                routeData.Values["action"] = "HttpError404";
            }

        Server.ClearError();
        Response.Clear();
        IController errorController = new ErrorController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
}

Upvotes: 6

Chris Moschini
Chris Moschini

Reputation: 37957

This can also help when dealing with MVC catchall problems:

routes.MapRoute(
    "Default",                                              // Route name
    "{controller}/{action}/{*id}",                          // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

That is, where it says {id}, change it to {*id}. This allows the final id parameter to consume as much additional path as might be passed in. The default rule accepts this:

/person/name/joe

But not this:

/products/list/sortby/name

The second URL will throw a 404 without this modification to the route.

Upvotes: 0

Scott
Scott

Reputation: 850

Your first route will catch the most urls since you have defaults for the elements, you can visualize this using the route debugger from Phil Haack, see the link:

Route Debugger

Upvotes: 6

Min
Min

Reputation: 2975

MVC routes are checked in the order that they are entered.

Mysite/blah will be found by the default route. The controller will be blah, and the action is index.

When you entered the mysite/blah/blah/blah/blah route you gave it a route it could not map the default route to and then your catchall route was called.

For those other examples, did you notice if they had some error filters setup? I'm pretty sure the default asp.net mvc site has some error handling attributes on the pages already.

Upvotes: 3

Related Questions