控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

浅谈Route规则名称的作用,及MvcPatch的处理方式

作者:Jeffrey Zhao 出处:博客园 2010年02月03日 阅读:

国庆前的最后一天,我写了《关于ASP.NET Routing的几点内容》,其中谈论了ASP.NET Routing作用,设计目的,工作流程等等。不过我还有一个比较重要的东西一笔带过了,不知道您注意到了没有,在向ASP.NET Routing的RouteTable.Routes属性(一个RouteCollection对象)中添加Route规则的时候,我们会同时指定一个“名称”,在微软给出的官方“广告”中,似乎看不出这个名称有什么用。但事实上,它的功能非常关键。

  那么我们通过一个实际的例子来看一下,Route规则的“名称”到底有什么作用:

routes.MapRoute(
    "Article.List",                                         // route name
    "articles/{*searchCriteria}",                           // pattern
    new { controller = "Article", action = "List" });       // defaults

routes.MapRoute(
    "Product.List",                                         // route name
    "products/{*searchCriteria}",                           // pattern
    new { controller = "Product", action = "List" });       // defaults

 

  以上两个Route规则,分别是“文章(article)”和“产品(product)”的搜索URL。与微软“广告”中一直使用的{controller}/{action}/{id}不同,我们实际生产过程中,一些如controller或action这样的数据无法从URL中捕获到,因此我们只是“匹配URL”并且“指定默认值”。就“捕获URL”这方面,这样的配置非常完美。但是我也多次强调,Route规则还会负责“生成虚拟路径”。那么这样的配置在这方面会有什么问题呢?请看下面这个数据:

var data = new { controller = "Product", action = "List", searchCriteria = "..." }

  我们可以使用这个匿名对象来构造一个RouteValueDictionary,其中包含了生成虚拟路径所需要的数据。于是我们可能会调用这个方法来得到结果:

RouteTable.Routes.GetVirtualPath(requestContext, new RouteValueDictionary(data));

 

  很显然,这个数据是要生成“产品”的搜索路径,但是您猜一下,我们能够得到正确结果吗?

  不行。

  因为RouteCollection的GetVirtualPath方法会依次遍历其中所有Route对象,访问其GetVirtualPath方法,并把第一个非null参数作为结果。如果项目中的配置如以上两个,则这样的数据永远会被Article.List这个规则捕获到——于是生成的永远便是Article.List的虚拟路径了。

  对于这个问题一般有两种解决方法,一是为Route规则添加“约束”:

routes.MapRoute(
    "Article.List",                                         // route name
    "articles/{*searchCriteria}",                           // pattern
    new { controller = "Article", action = "List" },        // defaults
    new { controller = "Article", action = "List" });       // constraints

 

  于是,这个Route对象在生成虚拟路径的时候,就会关注当前的RouteValueDictionary中包含的值是否符合约束。如果不符合,则直接返回null。如此,RouteCollection便会继续尝试下一个Route规则——可能就是Product.List,于是我们得到了想要的数据。

  第二种解决方法便是在构造URL的时候指定一个名称:

RouteTable.Routes.GetVirtualPath(requestContext, "Product.List", new RouteValueDictionary(data));

 

  如此,RouteCollection便会直接去找到Product.List所对应的Route对象,并且直接使用它的GetVirtualPath方法获得虚拟路径——即使返回null,也不会尝试其他Route规则。这么做的好处是避免Route规则之间在生成虚拟路径时产生冲突,并且由于避免了便利所造成的无效尝试,于是程序性能也会有些许提高。

  在MvcPatch中也有对Route配置名称的支持:在MvcPatch.Extensions.dll中包含一个RouteNameAttribute对象,我们可以用它对某个Action方法进行标记,如:

[RouteName("Product.List")]
public ActionResult List(string searchCriteria)
{
    ...
}

 

  于是,如果您在View中使用这样的方法来构造URL:

<%= Url.Action<ProductController>(c => c.List(...)) %>

 

  MvcPatch便会查看这个Action方法是否有RouteName标记。如果有,则通过直接指定名称的方式去构造虚拟路径,否则便还是传统的“遍历”方式。

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统