Route matching with GetVirtualPath
I've got the following routing in my application...
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Branding",
"foo/bar.css",
new { controller = "DynamicContent", action = "CSS" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Account", action = "Index", id = UrlParameter.Optional }
);
}
I'm using Martijn Boland's paging mechanism and it eventually makes the following call:
var virtualPathData =
RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary);
I've verified that my controller and action in RequestContext are valid. But once this call is made, virtualPathData references th开发者_C百科e URL for foo/bar.css. I have verified that URLs map to the correct controller/action. If I comment out the route above leaving the default, virtualPathData's URL corresponds to the right controller/action.
I've also tried the following line and I have the same result.
//var virtualPathData =
RouteTable.Routes.GetVirtualPathForArea(this.viewContext.RequestContext, pageLinkValueDictionary);
Can anyone help me figure out what I'm doing wrong?
Unfortunately, I think the logic for generating URLs doesn't handle static URLs very well. I believe one thing you can do is:
routes.MapRoute(
"Branding",
"{controller}/bar.css",
new { controller = "DynamicContent", action = "CSS" },
new {controller="foo"}
);
Try that out.
I'm still not exactly sure why I was seeing the behavior above, so if anyone wants to chime in with their ideas feel free.
That said, if someone else hits the same problem, I was able to overcome it by reversing the route order with the more ambiguous default route being added first with a NotEqual constraint to ensure that the DynamicContent route was hit as needed.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Account", action = "Index", id = UrlParameter.Optional },
new { controller = new NotEqual("DynamicContent") }
);
routes.MapRoute(
"Branding",
"foo/bar.css",
new { controller = "DynamicContent", action = "CSS" }
);
For those who are wondering what NotEqual is, I found it on a blog.
public class NotEqual : IRouteConstraint
{
private string _match = string.Empty;
public NotEqual(string match)
{
_match = match;
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return String.Compare(values[parameterName].ToString(), _match, true) != 0;
}
}
I'm certainly up for hearing about better ways of doing this OR why my original code wasn't completely working.
精彩评论