ASP.NET MVC - Intercepting the RouteValueDictionary
ASP.NET MVC Preview 3 suffers from a bug where the controller name is omitted from the RouteValueDictionary when you call Html.ActionLink or Url.Action unless you explicitly specify it.
Imagine you have the following routes defined:
routes.Add(new Route("Other/List", new RouteValueDictionary(new { controller = "Other", action = "List" }), new MvcRouteHandler()) ); routes.Add(new Route("{controller}/{action}/{id}", new RouteValueDictionary(new { action = "Index", id = (string)null }), new MvcRouteHandler()) );
..and you have a HomeController with two actions: Index and List
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult List() { return View(); } }
And imagine the following code in the Index view:
<%= Url.Action("List") %>
This should generate MyApp/Home/List but instead it generates MyApp/Other/List.
To work around this, you can intercept the RouteValueDictionary before it is passed to your routes by adding a route 'pre-parser'. In here, you can copy the controller name from the routedata into the RouteValuesDictionary.
public class RouteValuePreParser : RouteBase { public override RouteData GetRouteData(HttpContextBase httpContext) { return null; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { if(!values.ContainsKey("controller") && requestContext.RouteData.Values.ContainsKey("controller")) { values.Add("controller", requestContext.RouteData.Values["controller"]); } return null; } }
You can then add this 'fake' route to your RouteTable, but it must be the first route:
RouteTable.Routes.Add(new RouteValuePreParser());