0

I'm using ASP.net MVC4 with VWD Express 2010. I've set up an extra route to remove the extraneous /Home/ from URLs, as suggested for example here and here. I made sure to put them in the right order:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

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

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

This works as far as removing /Home/ is concerned, but now I get 404 when trying to access non-default controllers:

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

Requested URL: /LogItem/

I've tracked it down to the route, since if I remove the non-default one, it works fine again. I'm not sure what I'm doing wrong however, and by my understanding of other answers and the docs, this should work.

Edit: Since it's apparently not clear from my description, I added the "Home" route to be able to link to /About/ instead of /Home/About, etc. It was the suggested solution I found after googling. I basically want it to match actions implemented by HomeController with shorthand URLs (/{action}), as well as any other controller I also add in full (/{controller}/{action}/{optional id})

Community
  • 1
  • 1
mathrick
  • 217
  • 2
  • 11

1 Answers1

0

Routes are evaluated on a first-come, first-served basis. Your "Home" route basically says "If you see a URL with just one segment - grab it and handle it, then assume that segment is the action. When that happens, the second route you've registered doesn't get a chance to handle the request.

With the specific error as an example, you are requesting "/LogItem". The Home route kicks in, parses "LogItem" as the name of the action, and passes it to the default controller. Since that controller maybe doesn't have a LogIn action, a 404 is thrown.

One solution is to change the order of the routes. But even then, those two are overlapping, since the 2nd will also handle URLs with 1 segment, but interpret that segment as the controller. It will execute the default action (Index) rather than passing the handling to the next route.

Why do you need the first route? What are you trying to achieve? If you provide more context we can figure out a way to implement those routes.

Slavo
  • 15,255
  • 11
  • 47
  • 60
  • I don't think that you can have both /{action}, as well as /{controller}/{action} routes. No matter what their order is, the first will always handle the request and prevent the other from doing so. You can create separate routes for each specific page you want (i.e. /About, /Contact, etc.), instead of /{action}. This will pass the handling to the next route, unless it's one of those URLs. – Slavo Oct 24 '13 at 13:29
  • That's a pity. I thought the matching would take into account the implemented actions in each controller, and the other answers I linked certainly led me into believing that'd work. – mathrick Oct 24 '13 at 13:40