之前对Controller创建的分析中,知道了Controller的创建是有两个步骤组成,分别是Controller的类型查找以及根据类型创建Controller实例。

  在查询Controller的类型时,实际上是通过RouteData中的Controller名称和命名空间来完成匹配和查找的,而Controller的名称就根据路由对象中的url模板来获取,如默认的url模板:"{controller}/{action}/{id}"。以下是根据ControllerName查找Controller类型的方法,需要注意的是,在通过Controller名称查找之前还有一个判断,当RouteData不为空且被匹配为直连路由时,会通过另外的逻辑使用RouteData获取一个Controller类型。代码如下:

   

  DirectRoute是什么?本章将从以下几点介绍直连路由相关内容:
  ● 什么是直连路由
  ● 如何在MVC中使用直连路由
  ● 直连路由与约定路由的区别
  ● 为什么使用直连路由

什么是直连路由

  直连路由又称为特性路由(Attribute Routing),因为它是通过特性的方式将路由的匹配模板直接应用到Action方法上。如下图代码中的action需要使用http://XXX/dr/test才能够正常访问:

  

  其中Route特性的定义如下:

  

  从其定义可以看出Route特性可以应用在Controller以及Action上。通过Route特性可以直接为action指定路由。

  那么对于程序来说什么是直连路由呢?从最初给出的代码来看,代码层面是通过RouteData.HasDirectRouteMatch方法来判断的,下图是判断逻辑,非常简单仅仅判断Value中是否包含名称为“MS_DirectRouteMatches”的Key值。换句话说,RouteData中包含“MS_DirectRouteMatches”这个Key值的就是直连路由。

  

如何在MVC中使用直连路由

  ASP.NET MVC中有一个对路由表的拓展对象RouteCollectionAttributeRoutingExtensions,其定义如下图所示,它的功能就是将当前应用中使用特性定义的路由注册到路由表中。

  

  所以在注册路由时加入以下代码即可:

  

  在项目中添加以下测试代码:

  

  运行程序后可以看到dr/test以及dr/test2均被添加到路由表中:

  

  并且在对应的路由信息中包含了Controller和action的信息:

  

  

  注:此处添加了三条路由信息,其中一条它的值是一个RouteCollectionRoute类型,就是说该路由表又包含了一个路由表,被包含的这个路由表中的内容是该程序中所有通过Route特性生成的,另外的两个LinkGenerationRoute则就表示通过特性生成的路由。换句话说一个特性标记会生成两条路由信息,但为什么一个特性标记会在两个路由表中都插入路由对象本章节不再深入分析。
  关于如何在直连路由中使用默认值、路由前缀、默认路由、路由约束、直连路由的Area等功能可参考这篇文章:https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/

直连路由与约定路由的区别

  相对于直连路由来说,使用Controller和Action匹配的路由被称为基于约定的路由,因为请求url中携带了约定好的Controller和Action的名称。它们的区别主要有以下几点:
  1. 直连路由与约定路由,路由的注册方式不同,前者通过查找所有Controller类型中是否使用Route特性来创建路由。后者通过在配置文件中自行添加。
  2. 直连路由在注册时将对应的Controller和Action的信息包含到了Route对象中,而约定的路由是在解析时通过url模板匹配获得Controller和Action信息。
  3. 当Action被Route特性标记后,Controller的类型查找不再会通过基于约定的路由的Controller类型查找逻辑。
  4. 当Action被Route特性标记后并且项目中使用了基于约定的路由,那么使用基于约定的路由方法是访问不到被标记的action的,因为查找Action的逻辑中它们两种路由是分开的:

  

  5. 直连路由请求中的RouteData自动添加了MS_DirectRoute相关的值,如下:

  

为什么使用直连路由

  直连路由最主要的特性就是路由与实际代码在同一个文件里,这样在代码阅读时更容易将路由与实际的Action进行匹配,另外使用直连路由可以根据实际的需求来“创造”一个更符合需求的url“新约定”,同时也可以避免基于约定的路由对代码内部实现的暴露。

小结

  本章通过在MVC的源码中发现两种不同的Controller、Action处理方式引出了直连路由的概念,实际上这是MVC5中加入的新特性,可以使用特性的方式指定对应的action的路由模板。但要注意的是尽量避免两种路由方式的混用造成代码混乱。

参考:

  https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/

本文链接:http://www.cnblogs.com/selimsong/p/7722988.html

ASP.NET没有魔法——目录

ASP.NET没有魔法——ASP.NET MVC 直连路由(特性路由)的更多相关文章

  1. ASP.NET没有魔法——ASP.NET MVC 与数据库大集合

    ASP.NET没有魔法——ASP.NET与数据库 ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL ASP.NET没有魔法——ASP.NET MVC 与数据库之ORM ASP.N ...

  2. ASP.NET没有魔法——ASP.NET MVC 路由的匹配与处理

    ASP.NET MVC的路由是MVC应用的一个核心也是MVC应用处理的入口,作为一个开发者,在正常情况下仅仅需要做的就是根据需求去定义实体.业务逻辑,然后在MVC的Controller中去调用.Vie ...

  3. ASP.NET没有魔法——ASP.NET MVC IoC

    之前的文章介绍了MVC如何通过ControllerFactory及ControllerActivator创建Controller,而Controller又是如何通过ControllerBase这个模板 ...

  4. ASP.NET没有魔法——ASP.NET MVC 过滤器(Filter)

    上一篇文章介绍了使用Authorize特性实现了ASP.NET MVC中针对Controller或者Action的授权功能,实际上这个特性是MVC功能的一部分,被称为过滤器(Filter),它是一种面 ...

  5. ASP.NET没有魔法——ASP.NET MVC使用Oauth2.0实现身份验证

    随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...

  6. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)

    上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...

  7. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染

    对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的界面呈现工作是由浏览器完成的,Web应用的原理是通过Http协议从服务器上获取到 ...

  8. ASP.NET没有魔法——ASP.NET MVC Razor与View渲染 ASP.NET没有魔法——ASP.NET MVC界面美化及使用Bundle完成静态资源管理

    ASP.NET没有魔法——ASP.NET MVC Razor与View渲染   对于Web应用来说,它的界面是由浏览器根据HTML代码及其引用的相关资源进行渲染后展示给用户的结果,换句话说Web应用的 ...

  9. ASP.NET没有魔法——ASP.NET 身份验证与Identity

    前面的文章中为My Blog加入了文章的管理功能(ASP.NET没有魔法——ASP.NET MVC使用Area开发一个管理模块),但是管理功能应该只能由“作者”来访问,那么要如何控制用户的访问权限?也 ...

  10. ASP.NET没有魔法——ASP.NET Identity 的“多重”身份验证

    ASP.NET Identity除了提供基于Cookie的身份验证外,还提供了一些高级功能,如多次输入错误账户信息后会锁定用户禁止登录.集成第三方验证.账户的二次验证等,并且ASP.NET MVC的默 ...

随机推荐

  1. java第一次作业0

    lsl321 java第一次作业 #1. 本章学习总结 你对于本章知识的学习总结 本章我们学习了各种java相关文件的使用,以及码云,博客,pat等程序辅助软件,这些对于我们专业的学习有非常大的帮助, ...

  2. 201521123074 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 Q1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  3. Markdow使用的简单介绍

    一个例子: 例子开始 1. 本章学习总结 (字体较大,用法:#你要放大的标题) 今天主要学习了三个知识点 封装 继承 多态 用法: - 封装 - 继承 - 多态 2. 书面作业 Q1. java He ...

  4. POJ 3190 Stall Reservations (优先队列)C++

    Stall Reservations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7646   Accepted: 271 ...

  5. mysql 安装-zip版

    1.千万不要自己新建data,使用命令:mysqld --initialize会自动生成一大堆文件 2.没有ini文件就自己新建:

  6. 在JavaScript中使用json.js:Ajax项目之GET请求(同步)

    1.用php编写一个提供数据的响应程序(phpdata.php) <?php $arr=array(1,2,3,4); //将数组编码为JSON格式的数据 $jsonarr=json_encod ...

  7. 什么是PWM信号

    PWM信号脉宽调制PWM是开关型稳压电源中的术语.这是按稳压的控制方式分类的,除了PWM型,还有PFM型和PWM.PFM混合型.脉宽宽度调制式(PWM)开关型稳压电路是在控制电路输出频率不变的情况下, ...

  8. Linux入门(7) 脚本

    1.宣告使用的shell为何 2.注明创建者 编写作用等 3.注释每一个功能函数 执行脚本 1.修改可执行权限 chmod 755 file.sh 2.sh file.sh 可以直接运行脚本 #!/b ...

  9. POJ-1273-Drainage Ditches(网络流之最大流)

    Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This ...

  10. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...