开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜