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());