软件下载 | 资讯教程 | 最近更新 | 下载排行 | 一键转帖 | 发布投稿
您的位置:最火下载站 > 网络编程 > ASP教程 > 浅谈Route规则名称的作用及MvcPatch的处理方式

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

国庆前的最后一天,我写了《关于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标记。如果有,则通过直接指定名称的方式去构造虚拟路径,否则便还是传统的“遍历”方式。

作者博客:http://www.cnblogs.com/JeffreyZhao/

    相关阅读
    栏目导航
    推荐软件