详解ASP.NET MVC 路由 (下)

2017 年 7 月 21 日 DotNet

(点击上方蓝字,可快速关注我们)


来源:Alan_beijing

cnblogs.com/wangjiming/p/7040843.html


三、路由概述(特性路由)


特性路由是在ASP.NET MVC 5中新增的,传统路由ASP.NET MVC 1中就有了。


从内容上来看,特性路由的内容与传统路由差不多,同样有路由URL、路由值、控制器路由、路由约束和路由默认值等。鉴于篇幅限制,在这里就简单的概述一下,不作详细论述,后期有时间或者有朋友需要,再论述。


定义:特性路由就是将路由URL定义在控制器上或控制器内的方法上,而不像传统路由将路由URL定义在RouteConfig.cs中。对比如下


 


四、路由生成URL


路由两个重要职责:匹配传入的URL请求和构造与特定路由对应的URL,概括之匹配URL和构造URL。在生成URL时,生成URL的情趣应该首先与选择用来生成URL的路由相匹配,这样路由就可以在处理传入或传出的URL时成为完整的双向系统。原则上,开发人员应该提供一组路由值,以便路由系统从中选中第一个能够匹配URL的路由。


4.1 URL生成的高层系概述


路由的核心是一个非常简单的算法,该算法基于一个由RouteCollection类和RouteBase类组成的简单抽象对象。可以采用多种方法来生成URL,但这些方法都以调用RouteCollection.GetVirtualPath的一个重载方法而结束。RouteCollection.GetVirtulPath方法公有两个重载版本,下面的代码展示它们的方法签名:


public  VirtualPathData GetVirtualPath(RequestContext requestContex,RouteValueDictionary values)


public  VirtualPathData GetVirtualPath(RequestContext requestContex,string name,RouteValueDictionary values)


第一个重载版本接受当前的RequestContext,以及由用户指定的路由值(字典)。


(1)路由集合通过RouteBase.GetVirtualPath方法遍历每个路由并访问:“可以生成给定参数的URL吗”,这个过程类似于在路由与传入请求匹配时所运用的匹配逻辑。


(2)如果一个路由可以应答上面的问题(即匹配),那么它就会返回一个包含了

URL的VirTualPathData实例以及其他匹配的信息。否则,它就返回空值,路由机制移向列表中的下一个路由。


第二个重载接受三个参数,其中第二个参数是路由名称。在路由集合中路由名称是唯一的,也就是说,没有两个不同的路由具有相同的名称。当指定了路由名称时,路由集合就不需要循环遍历每个路由,相反,它可以立即找到指定名称的路由,并移向上面的步骤(2)。如果找到的路由不能匹配指定的参数,该方法就会返回空值,并且不再匹配其他路由。


4.2  URL生成详解


(1)开发人员调用像Html.ActionLink或Url.Action之类的方法,这些方法反过来再调用RouteCollection.GetVirtualPath方法,并向它传递一个RequestContext对象、一个包含值的字典以及用来选择生成URL的路由名称(可选参数)。


(2)路由机制查看要求的路由参数(即没有提供路由参数的默认值),并确保提供的路由值字典为每一个要求的参数提供一个值,否则,URL生成程序就会立即停止,并返回空值。


(3)一些路由可能包含没有对应路由参数的默认值。如路由可能为category键提供默认值“pastries”,但是cateory不是路由URL的一个参数,这种情况下,如果用户传入的路由值字典为category提供了一个值,那么该值必须匹配category的默认值。


(4)然后路由系统应用路由约束。


(5)路由匹配成!现在可以通过查看每一个路由参数,并尝试利用字典中的对应值填充相应参数,进而生成URL。


可以概括为如下流程图:


 

五、路由绑定到操作


在这一章节,主要分析URL绑定到控制器操作的底层细节,分析底层原理,理解ASP.NET请求管道。注意,目前路由不仅仅只是ASP.NET MVC的一个特性了,它已经超过这个范围,如ASP.NET Dynamic Data。路由既不包括MVC的内部知识,也不依赖于MVC。


5.1 高层次请求的路由管道


当ASP.NET 处理请求时,路由管道主要由以下几步组成:


(1)UrlRoutingModule尝试使用在RouteTable中注册的路由匹配当前请求。


(2)如果RouteTable中有一个路由成功匹配,路由模块就会从匹配成功的路由中获取IRouteHandler接口对象。


(3)路由模块调用IRouteHandler接口的GetHandler方法,并返回用来处理请求的IHttpHandler对象。


(4)调用HTTP处理程序中的ProcessRequest方法,然后把要处理的请求传递给它


(5)在ASP.NET MVC中,IRouteHandler是MvcRouteHandler类的一个实例,MvcRouteHandler转而返回一个实现了IHttpHandler接口的MvcHandler对象。返回的MvcHandler对象主要用来实例化控制器,并调        用该实例化的控制器上的操作方法。


5.2 路由数据


调用GetRouteData方法会返回RouteData的一个实例。RouteData中包含了关于匹配请求的路由信息。


如URL:{Controller}/{action}/{id}。当请求/albums/list/123传入时,该路由就会尝试匹配传入的请求,如果匹配成功,它就创建一个字典,其中包含了从URL中解析出的信息。


确切地讲,路由还会向Values字典中为URL中的每个路由参数添加一个键;对于传统路由{Controller}/{action}/{id},Values字典中应该至少包含三个键,分别是Controller,action和id,如果传入的URL是对/albums/list/123的请求,路由就会解析该请求的URL,并为字典的键提供值。


本例中,字典中“Controller”键的值为albums,"action"键的值为“list”,"id"键的值是“123”;对于特性路由MVC使用DataTokens字典来存储更精确的信息,而不是操作名称字符串。具体来说,它包含一个操作描述符列表,这些描述符直接指向路由匹配时可能使用的操作方法。对于控制器级别的特性路由,列表中将有不止一个操作。在整个MVC中都有用到的RequestContext的RouteData属性保存着外界路由值。


六、路由调试


使用RouteDebugger调试,启用RouteDebugger后,它会用一个DebuggerRouteHandler替换所有路由处理程序,DebugRouteHandler截获所有传入的请求,并查询路由表中的每一个路由,以便在页面底部显示路由的诊断数据和参数。


为使用RouteDebugger,只需在VS的Package Manager Console窗口中使用NuGet安装即可,命令Install-Package routedebugger.。RouteDebugger包在添加Route Debugger程序集的同时。也在web.config文件的appSettings节点中添加一个设置,用来开启或禁用路由调试。


<add key="RouteDebugger:Enable" value="true'>


只要启用RouteDebugger,它就显示从(在地址栏中)当前请求URL中提取的路由数据。如此,可以在地址栏中输入各种URL,并查看输入的URL能与哪个路由匹配,在页面底部,它还会展示一个包含应用程序定义的所用路由列表,这样可以查看定义的哪个路由能够与当前URL相匹配。


安装教程如下:


视图=>其他窗口=>程序包管理控制台



在窗口中输入:Install-Package routedebugger



或者也可以使用NuGet很方便的安装RouteDebugger,在项目上面右键-"Manage NuGet Packages"-"Online"输入"RouteDebugger"然后"Install".


当然, 你也可以自己下载RouteDebugger.dll, 引用到web项目中, 然后手动在web.config中加入


<add key="RouteDebugger:Enabled" value="true" />


测试结果


RouteConfig.cs


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;


namespace MVCDemo

{

    public class RouteConfig

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.MapMvcAttributeRoutes();//


            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


            routes.MapRoute(

                name: "Default",

                url: "{controller}/{action}/{id}",

                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

            );

        }

    }

}


RouteDemoController


using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;


namespace MVCDemo.Controllers

{

    public class RouteDemoController : Controller

    {

        //

        // GET: /RouteDemo/

        public ActionResult Index()

        {

            return View();

        }

    }

}


Index


@inherits System.Web.Mvc.WebViewPage

<h2>RouteDebugger调试</h2>



七、与路由相关的关键命名空间和类


7.1  路由涉及的命名空间



7.2 Class Reference( 路由涉及到的关键类)


 

八、 总结


由于篇幅有限,路由章节就写到这,当然,还有很多内容没写,如路由配置文件、路由安全设置、自定义路由约束等,留给读者朋友们研究。


参考文献


【01】https://msdn.microsoft.com/en-us/library/cc668201.aspx#setting_default_values_for_url_parameters


【02】http://www.cnblogs.com/willick/p/3343105.html


【03】https://msdn.microsoft.com/zh-cn/library/cc668201(v=vs.100).aspx


【04】Professional Asp.net MVC 5


【05】http://www.cnblogs.com/liangxiaofeng/p/5620033.html


【06】https://msdn.microsoft.com/en-us/library/cc668177.aspx


【07】https://msdn.microsoft.com/en-us/library/dd535620.aspx


【08】https://msdn.microsoft.com/en-us/library/cc668176.aspx


【09】https://msdn.microsoft.com/en-us/library/dd329551.aspx


【10】https://msdn.microsoft.com/en-us/library/system.web.routing.route.aspx


【11】https://msdn.microsoft.com/en-us/library/system.web.routing.pageroutehandler.aspx


【12】https://msdn.microsoft.com/en-us/library/system.web.mvc.mvcroutehandler.aspx


【13】https://msdn.microsoft.com/en-us/library/system.web.ui.page.routedata.aspx


【14】https://msdn.microsoft.com/en-us/library/bb398900.aspx


【15】https://msdn.microsoft.com/en-us/library/ee941656.aspx


看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能 

登录查看更多
0

相关内容

ASP.NET MVC Framework 是微软官方提供的 MVC 模式编写 ASP.NET Web 应用程序的一个框架。它由 Castle 的 MonoRail 而来。已于 2009 年 3 月 19 日正式发布,目前已经历经数个版本。
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【AAAI2020知识图谱论文概述】Knowledge Graphs @ AAAI 2020
专知会员服务
133+阅读 · 2020年2月13日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
手把手教你用Python实现“坦克大战”,附详细代码!
机器学习算法与Python学习
11+阅读 · 2019年6月8日
从webview到flutter:详解iOS中的Web开发
前端之巅
5+阅读 · 2019年3月24日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
JavaScript 背包问题详解
前端大全
7+阅读 · 2018年1月17日
手把手丨用TensorFlow开发问答系统
大数据文摘
21+阅读 · 2017年11月29日
tensorflow LSTM + CTC实现端到端OCR
数据挖掘入门与实战
8+阅读 · 2017年11月15日
Arxiv
21+阅读 · 2019年3月25日
Arxiv
3+阅读 · 2019年3月1日
Rapid Customization for Event Extraction
Arxiv
7+阅读 · 2018年9月20日
Arxiv
5+阅读 · 2018年5月1日
VIP会员
相关VIP内容
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【AAAI2020知识图谱论文概述】Knowledge Graphs @ AAAI 2020
专知会员服务
133+阅读 · 2020年2月13日
Transformer文本分类代码
专知会员服务
116+阅读 · 2020年2月3日
TensorFlow Lite指南实战《TensorFlow Lite A primer》,附48页PPT
专知会员服务
69+阅读 · 2020年1月17日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
相关资讯
手把手教你用Python实现“坦克大战”,附详细代码!
机器学习算法与Python学习
11+阅读 · 2019年6月8日
从webview到flutter:详解iOS中的Web开发
前端之巅
5+阅读 · 2019年3月24日
去哪儿网开源DNS管理系统OpenDnsdb
运维帮
21+阅读 · 2019年1月22日
JavaScript 背包问题详解
前端大全
7+阅读 · 2018年1月17日
手把手丨用TensorFlow开发问答系统
大数据文摘
21+阅读 · 2017年11月29日
tensorflow LSTM + CTC实现端到端OCR
数据挖掘入门与实战
8+阅读 · 2017年11月15日
Top
微信扫码咨询专知VIP会员