haacked/routemagic

MapDelegate overrides default routing when calling with Html.ActionLink

Buildstarted opened this issue · 2 comments

Given the following routes

routes.MapDelegate("RouteFailureTest", "home/test",
context => new HomeController().HomeTest(context.HttpContext));

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

a call to @Html.ActionLink("Log Off", "Logout", "User") always matches the "RouteFailureTest".

My guess is that it's related to the lack of default controller/action values so the ActionLink, providing the default values matches the delegate route.

It's fairly simple to reproduce, use a standard MVC3 application (with default Home/Account controllers) add the MapDelegate route above and check the Login/Home/About Us links. They will always match the RouteFailureTest route.

routes.MapRoute(
"ShouldntMatch", // Route name
"home/test", // URL with parameters
null // Parameter defaults
);

Confirmed it's the null defaults. This route produces the same results as the MapDelegate by matching any Html.ActionLink or other similar helpers

This is an issue with the underlying ASP.NET Routing. Read http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx for more details.

We could in theory fix it by having MapDelegate return a route that checks to see if the URL pattern has any parameters (aka sections with {curlybraces}) and if it doesn't, the route doesn't implement GetVirtualPath. That's the method that generates a URL. What that would mean is such an URL cannot be used for URL generation.

Seem reasonable?

Interesting. It makes sense now that I read that. However since a lot of people use the default RouteLink/ActionLink and their ilk without specifying a named routes I'm pretty sure it's reasonable to handle it in the way you specify.