GetVirtualPathForArea返回错误的VirtualPath

时间:2011-09-04 20:19:38

标签: c# asp.net-mvc asp.net-mvc-3

我使用的是Martijn Bolands paging,我遇到了GetVirtualPathForArea方法的问题。

我有两页:/ Page1和/ Page2。

我为/ Page1设置了一个MapRoute,并以/ Page1Name

的形式访问
routes.MapRoute(
      "Page1 name", // Route name
       "Page1Name", // URL with parameters
       new { controller = "ContollerName", action = "ActionName" } // Parameter defaults
);

如果我尝试从Page1Name页面获取Vitrual路径,它会给我正确的路径。

但是!!如果我尝试从第2页获取虚拟路径,它会再次为我提供Page1Name。

我没有为Page2设置任何路由,如果这样做,那么在Page1中我将获得Page2的VirtualPath。

通话和方法

通过HtmlHelper进行呼叫,如下所示

public static HtmlString Pager(this HtmlHelper htmlHelper, int pageSize, int currentPage, int totalItemCount, string actionName, RouteValueDictionary valuesDictionary, string controllerName) {
        if (valuesDictionary == null) {
            valuesDictionary = new RouteValueDictionary();
        }
        if (actionName != null) {
            if (valuesDictionary.ContainsKey("action")) {
                throw new ArgumentException("The valuesDictionary already contains an action.", "actionName");
            }
            valuesDictionary.Add("action", actionName);
        }
        var pager = new Pager(htmlHelper.ViewContext, pageSize, currentPage, totalItemCount, valuesDictionary, null, controllerName);
        return pager.RenderHtml();
    }

这是来自RenderHtml()方法

它从htmlHelper获取viewContext,这是获取virtualPath的调用

var pageLinkValueDictionary = new RouteValueDictionary(linkWithoutPageValuesDictionary) { { "page", pageNumber } };
var virtualPathForArea = RouteTable.Routes.GetVirtualPathForArea(viewContext.RequestContext, pageLinkValueDictionary);

这是一个已知问题吗?我是否以错误的方式设置了某些内容?

谢谢,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

来自微软的回复:

你在这里提到的行为实际上是“按设计”,如果路由URL(例如你的第一个路由:FirstPage)没有参数,没有默认值,没有约束,则调用RouteTable.Routes.GetVirtualPathForArea( )将匹配此路线(当它到达它时,它尝试按照添加的顺序逐个匹配路线)。 一般的解决方法是使其中一个条件为假或使用命名路由。

您可以在Phil Haack的博客文章中阅读更多相关信息:http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx

答案 1 :(得分:0)

通常,注册的路线可能看起来像

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

意味着执行Url.Action("Index","Home", new {id = 1})会产生网址/Home/Index/1; {controller}/{action}/{id}是占位符,用于解释请求(使用哪个控制器,操作和参数)和生成URL。

如果您查看定义的路线(如果它是唯一的路线,或定义为第一路线),无论您使用Url.Action(..)做什么,它都将始终返回/Page1Name

如果您想在提供的链接中执行

  

在内部,寻呼机使用RouteTable.Routes.GetVirtualPath()来呈现网址,以便可以通过路由配置页面网址以创建漂亮的网址,例如/Categories/Shoes/Page/1而不是/Paging/ViewByCategory?name=Shoes&page=1。< / p>

然后您可以注册您的路线,如:

routes.MapRoute(
    "PagingRoute", // Route name
    "Categories/{type}/Page/{page}", // URL with parameters
    new { controller = "PagingControllerName", 
          action = "Index", 
          type = UrlParameter.Optional, 
          page = UrlParameter.Optional } // Parameter defaults,
);

并且PagingController中的匹配方法是

public ActionResult Index(string type, int? page) { // do something}

更新

如果您正在使用Martijn Bolands寻呼机,请查看他映射/注册的第二条路线:

routes.MapRoute("SimplePaging", "SimplePaging/{page}",  
    new { controller = "Paging", action = "Index", page = UrlParameter.Optional },
new[] { "MvcPaging.Demo.Controllers" });

那么你的内容应该差不多(即添加UrlParameter页面)。但这意味着你的网址总是看起来像/ Page1Name / [pagenumber]。另一方面,如果Page1Name是您的实际操作,则应将路由定义为:

routes.MapRoute("Page1 name", "{action}/{page}",    
    new { controller = "Paging", action = "Page1Name", page = UrlParameter.Optional },
);