这段时间在读园子里Artech大神的《ASP.NET MVC5框架揭秘》,慢慢地从底层了解了MVC模式的设计思路。下面是一些阅读的总结。

传统的Web Forms应用,URL指向的是具体的物理文件,而ASP.NET MVC应用一般指向的是某个Controller中的某个Action方法。URL与目标Controller/Action之间的映射关系是通过“路由”来实现的。

路由系统中的几个核心类的描述:

RouteBase

  • 一个抽象基类。
  1. public abstract class RouteBase
  2. {
     //.NET Framwork4.5以下无该属性(是否对物理文件采取路由)
  3. public bool RouteExistingFiles { get; set; }
     //获取路由数据
  4. public abstract RouteData GetRouteData(HttpContextBase httpContext);
     //路由解析生成一个完整的路径
  5. public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
  6. }

RouteData

  • 封装了有关路由的信息。
  • RouteData通过其RouteHandler属性返回一个RouteHandler对象。
  • RouteHandler实现IRouteHandler中的GetHttpHandler(RequestContext requestContext),返回一个具的HttpHandler对象接管http请求。
  1. public class RouteData
  2. {
  3. public RouteData();
  4. public RouteData(RouteBase route, IRouteHandler routeHandler);
  5. public string GetRequiredString(string valueName);
  6.  
  7. public RouteBase Route { get; set; }
  8. public IRouteHandler RouteHandler { get; set; }
  9.      public RouteValueDictionary DataTokens { get; }
  10. public RouteValueDictionary Values { get; }
  11. }

VirtualPathData

  • 表示有关路由和虚拟路径的信息。
  • 执行RouteBase的GetVirtualPath()会进行路由匹配,将路由变量去替换路由模板中的占位符并生成虚拟路径。
  • 此类为虚拟路径和Route的封装。
  1. public class VirtualPathData
  2. {
  3.   public VirtualPathData(RouteBase route, string virtualPath);
  4.   public RouteValueDictionary DataTokens { get; }
  5.   public RouteBase Route { get; set; }
  6.   public string VirtualPath { get; set; }
  7. }

 Route

  • 提供用于定义路由及获取路由相关信息的属性和方法。
  • 路由解析由路由表中具体的某个Route对象来完成。
  1. public class Route : RouteBase
  2. {
  3. public Route(string url, IRouteHandler routeHandler);
  4. public Route(string url, RouteValueDictionary defaults, IRouteHandler routeHandler);
  5. public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler);
  6. public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler);
  7. //约束(可用正则)
  8. public RouteValueDictionary Constraints { get; set; }
         //存储额外的变量,不参与路由解析
  9. public RouteValueDictionary DataTokens { get; set; }
  10. public RouteValueDictionary Defaults { get; set; }
  11. public IRouteHandler RouteHandler { get; set; }
  12. public string Url { get; set; }
  13.  
  14. public override RouteData GetRouteData(HttpContextBase httpContext);
  15. public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
  16. }

 RouteTable

  • 存储应用程序的 URL 路由。
  • 静态只读属性Routes访问全局路由表。
  1. public class RouteTable
  2. {
  3. public static RouteCollection Routes { get; }
  4. }

RouteCollection

  • 一组Route的集合,用来操作Route。
  • 调用RouteCollection的GetRouteData和GetVirtualPath时会遍历集合中的所有Route。
  • 常用的两个方法。MapPageRoute:注册路由。Ignore:忽略对应的URL格式。


总结下类之间的关系:

Route对象代表一条实际的路由规则。调用Route对象的两个路由匹配方法时进行路由解析,返回的RouteData或VirtualPathData是对Route的封装。RouteTable存储了Web应用的全局路由信息,即多个Route对象。

路由注册

  • MVC4中默认的路由注册
  1.   public static void RegisterRoutes(RouteCollection routes)
  2. {
  3. routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  4. routes.MapRoute(
  5. name: "Default",
  6. url: "{controller}/{action}/{id}",
  7. defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  8. );
  9. }
  • 书中带约束的注册方式
  1.    public static void RegisterRoutes(RouteCollection routes)
  2. {
           //默认值
  3. var defaults = new RouteValueDictionary{
  4. {"areacode",""},{"days",}};
           //正则约束
  5. var constaints = new RouteValueDictionary {
  6. {"areacode",@"0\d{2,3}"},{"days",@"[1-3]{1}"}};
           //说明
  7. var dataTokens = new RouteValueDictionary{
  8. {"defaultCitr\y","BeiJing"},{"defaultDays",}};
  9. routes.MapPageRoute("default","{areacode}/{}days","~/weather.aspx"
  10. ,false,defaults,constaints,dataTokens);
  11. }

正则约束是其中一个比较简单的方法,我们还可以通过自定义约束来实现。实现IRouteConstraint的Match方法。

假设现在我们要通过IRouteConstraint来限制IE浏览器的访问。

  1. public class IERouteConstraint : IRouteConstraint
  2. {
  3. public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
  4. {
  5. return !(httpContext.Request.UserAgent.Contains("MSIE"));
  6. }
  7. }
  1. //在原来的约束基础上修改
  2. var constaints = new RouteValueDictionary {
  3.     {"areacode",@"0\d{2,3}"},{"days",@"[1-3]{1}"},new IERouteConstraint()};

注:针对自定义路由约束的详细内容,请移步:http://www.cnblogs.com/xfrog/archive/2010/12/19/1910428.html。此例也选自该博文。

从HTTP请求到路由解析

  1. URLRoutingModule派生自IHttpModule。通过它注册HttpApplication的PostResolveRequestCache事件。
  2. 当一个HttpApplication对象触发该事件后,URLRoutingModule通过RouteTable的静态只读属性Routea得到全局的路由表的RouteCollection对象,然后根据当前的上下文创建一个HttpContextWrapper对象(派生自HttpContextBase),并将其作为参数调用RouteCollection对象的GetRouteData方法。
  3. 如果路由匹配成功,会返回一个具体的RouteData对象。
  4. URLRoutingModule会将HttpContextWrapper传入RouteData对象中的RouteHandler。调用它的GetHttpHandler方法,得到一个具体的HttpHandler。URLRoutingModule最后调用HttpContextWrapper对象的RemapHandler方法对得到的HttpHandler进行映射。
  5. 解析完成,针对当前的HTTP请求就由该Handler来接手。

注:本博文大多数内容来自《ASP.NET MVC5框架揭秘》中,只是做内容的梳理和总结。

ASP.NET 路由解析的更多相关文章

  1. ASP.NET路由模型解析

    大家好,我又来吹牛逼了 ~-_-~ 转载请注明出处:来自吹牛逼之<ASP.NET路由模型解析> 背景:很多人知道Asp.Net中路由怎么用的,却不知道路由模型内部的运行原理,今天我就给大家 ...

  2. ASP.NET Web API路由解析

    前言 本篇文章比较长,仔细思考阅读下来大约需要15分钟,涉及类图有可能在手机显示不完整,可以切换电脑版阅读. 做.Net有好几年时间了从ASP.NET WebForm到ASP.NET MVC再到ASP ...

  3. ASP.NET路由[ASP.NET Routing]

    ASP.NET路由[ASP.NET Routing] ASP.NET路由允许你在使用URL时不必匹配到网站中具体的文件,因为这个URL不必匹配到一个文件,你使用了描述用户行为且更容易被用户理解的URL ...

  4. ASP.NET路由系统实现原理:HttpHandler的动态映射

    我们知道一个请求最终通过一个具体的HttpHandler进行处理,而我们熟悉的用于表示一个Web页面的Page对象就是一个HttpHandler,被用于处理基于某个.aspx文件的请求.我们可以通过H ...

  5. ASP.NET Web API 框架研究 ASP.NET 路由

    ASP.NET Web API 如果采用Web Host方式来寄宿,在请求进入Web API 消息处理管道之前,就会用ASP.NET 自身的路由系统根据注册的路由表,解析出当前请求的HttpContr ...

  6. MVC路由解析---UrlRoutingModule

    文章引导 MVC路由解析---IgnoreRoute MVC路由解析---MapRoute MVC路由解析---UrlRoutingModule Area的使用 引言: 此文全文内容90%转自 一.前 ...

  7. AspNet Mvc 路由解析中添加.html 等后缀 出现404错误的解决办法

    使用Mvc 有时候我们希望,浏览地址以.html .htm 等后缀名进行结尾. 于是我们就在RouteConfig 中修改路由配置信息,修改后的代码如下 routes.IgnoreRoute(&quo ...

  8. ASP.NET 路由

    URL 模式可以包含文本值和变量占位符(也称为“URL 参数”).  文本和占位符位于由斜杠 (/) 字符分隔的 URL 段中. 当生成请求时,URL 分析为段和占位符,变量值提供给请求处理程序.  ...

  9. ASP.NET路由

    ASP.NET 路由使您可以使用不必映射到网站中特定文件的 URL. 由于该 URL 不必映射到文件,因此可以使用对用户操作进行描述因而更易于被用户理解的 URL. ASP.NET MVC 框架和 A ...

随机推荐

  1. Word文字处理器发展演变

    随着信息技术的不断发展,以前书面化的信笺,笔记,书籍以及作业演变成现在不断更新的电子化Word文档. Word是目前世界上最流行.最常用的文字编辑,排版软件,使用它不仅可以提高文档的编辑效率,在修改时 ...

  2. 【整理】--【GPIO】OK6410

    S3C6410的GPIO引脚相对来说比较多,而且大部分引脚都具有多重复用功能,如何在linux上用最简单的方式来控制GPIO这需要我们好好研究一下底层的代码了,其实方法有很多种,鉴于在操作系统端控制G ...

  3. monodb C#接口封装

    mongodb的C#封装,驱动是samus/mongodb-csharp 1.连接类 using MongoDB; using MongoDB.Linq; namespace DBModel { pu ...

  4. Task:取消异步计算限制操作 & 捕获任务中的异常

    Why:ThreadPool没有内建机制标记当前线程在什么时候完成,也没有机制在操作完成时获得返回值,因而推出了Task,更精确的管理异步线程. How:通过构造方法的参数TaskCreationOp ...

  5. 我的第一篇Markdown语法博客

    这是我的第一篇使用markdown语法编写的博客 使用的编辑器为Sublime Text2 并且使用了sublog插件, sublog是一个开源项目 sublog 并且参考了作者的博客 AmongOt ...

  6. hadoop研究:mapreduce研究前的准备工作

    继续研究hadoop,有童鞋问我,为啥不接着写hive的文章了,原因主要是时间不够,我对hive的研究基本结束,现在主要是hdfs和mapreduce,能写文章的时间也不多,只有周末才有时间写文章,所 ...

  7. 支持断点续传的文件上传插件——Huploadify-V2.0来了

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  8. 浅谈Excel开发:三 Excel 对象模型

    前一篇文章介绍了Excel中的菜单系统,在创建完菜单和工具栏之后,就要着手进行功能的开发了.不论您采用何种方式来开发Excel应用程序,了解Excel对象模型尤其重要,这些对象是您与Excel进行交互 ...

  9. 如何成为一个Xamarin专家

    近期,我们发布了 Xamarin studio 6,这个版本充满了美妙的新特性,能够更有效的帮助我们的开发工作.由于其深层次的 IDE 比较复杂,同时我们也很难去发现并记得那些对我们最有帮助的特性,所 ...

  10. “你没有权限登录JIRA”的解决办法

    为了更好的做部门的项目管理,部门老大让运维部署了一个jira系统.这两天让我试用并摸索如何用. jira默认的用户组有 jira-administrators.jira-developers.jira ...