IgnoreRoute in ASP.NET Routing is Order Dependent
Posted by: Steven Smith,
on 12 May 2009 |
View original | Bookmarked: 0 time(s)
Im wiring up the IoCControllerFactory from MVCContrib into an MVC application and I kept running into an issue where a request was coming in looking for a ContentController. The reason for this is that in my CSS file I have a property like this:
background: transparent url(images/logo.gif) no-repeat scroll left top;
which is in the Content folder. The resulting request for /Content/images/logo.gif was matching the default routing rule:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
and the result was that it excpeted to find a controller by the name of Content. I searched and found this post that had some useful ideas that I tried. At first, adding this had no effect:
routes.IgnoreRoute("{Content}/{*pathInfo}");
However, once I realized that the order mattered, and moved this to the top of my RegisterRoutes() method, it worked as expected.
I can understand that the ordering of the routes is important, for matching purposes, but its not intuitive to me that ignored routes should be order-dependent. I would think that there would be two lists in the RouteCollection, one for actual routes, and a separate one for ignored route patterns. The ignored routes would be checked every time, and anything that matched ignored (duh), while the actual routes would be checked in order, with the first matching route determining the appropriate controller to use. However, this doesnt appear to be the case.
The following will ignore the Content folder for routing purposes:
1:
public static void RegisterRoutes(RouteCollection routes)
2: {
3: routes.IgnoreRoute("{Content}/{*pathInfo}");
4:
5: routes.MapRoute(
6: "Default", // Route name
7: "{controller}/{action}/{id}", // URL with parameters
8: new { controller = "Home", action = "Index", id = "" } // Parameter defaults
9: );
10: }
The following will not ignore the Content folder:
1: public static void RegisterRoutes(RouteCollection routes)
2: {
3: routes.MapRoute(
4: "Default", // Route name
5: "{controller}/{action}/{id}", // URL with parameters
6: new { controller = "Home", action = "Index", id = "" } // Parameter defaults
7: );
8:
9: routes.IgnoreRoute("{Content}/{*pathInfo}");
10: }
It seems the actual implementation of IgnoreRoute is more of an actual MapRoute that simply maps to nothing. Thus, it follows all the same ordering logic that MapRoute follows. Once you make this realization, it makes sense, and of course youll want to put your IgnoreRoutes first (assuming you really want them to always be ignored) otherwise they wont be ignored.