路由常用对象

RouteBase

用作表示 ASP.NET 路由的所有类的基类。        就是路由的一个基础抽象类。

//
// 摘要:
// 用作表示 ASP.NET 路由的所有类的基类。
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public abstract class RouteBase
{
//
// 摘要:
// 初始化该类供继承的类实例使用。此构造函数只能由继承的类调用。
protected RouteBase(); //
// 摘要:
// 获取或设置一个值,该值指示 ASP.NET 路由操作是否应处理与现有文件匹配的 URL。
//
// 返回结果:
// 如果 ASP.NET 路由操作处理所有请求(甚至包括与现有文件匹配的请求),则为 true;否则为 false。默认值为 false。
public bool RouteExistingFiles { get; set; } //
// 摘要:
// 当在派生类中重写时,会返回有关请求的路由信息。
//
// 参数:
// httpContext:
// 一个对象,封装有关 HTTP 请求的信息。
//
// 返回结果:
// 一个对象,包含路由定义的值(如果该路由与当前请求匹配)或 null(如果该路由与请求不匹配)。
public abstract RouteData GetRouteData(HttpContextBase httpContext);
//
// 摘要:
// 当在派生类中重写时,会检查路由是否与指定值匹配,如果匹配,则生成一个 URL,然后检索有关该路由的信息。
//
// 参数:
// requestContext:
// 一个对象,封装有关所请求的路由的信息。
//
// values:
// 一个包含路由参数的对象。
//
// 返回结果:
// 一个对象(包含生成的 URL 和有关路由的信息)或 null(如果路由与 values 不匹配)。
public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}

是一个抽象类,里面两个抽象方法。(一般抽象类,抽象方法,虚方法  都是为了扩展用的           MVC最大的特点就是扩展,     1自身从原有的框架里面扩展来得。 2本身各个方面又支持扩展  )

Route

提供用于定义路由及获取路由相关信息的属性和方法。       他继承了RouteBase。

public class Route : RouteBase

1、构造函数

//
// 摘要:
// 使用指定的 URL 模式和处理程序类初始化 System.Web.Routing.Route 类的新实例。
//
// 参数:
// url:
// 路由的 URL 模式。
//
// routeHandler:
// 处理路由请求的对象。
public Route(string url, IRouteHandler routeHandler);
//
// 摘要:
// 使用指定的 URL 模式、默认参数值和处理程序类初始化 System.Web.Routing.Route 类的新实例。
//
// 参数:
// url:
// 路由的 URL 模式。
//
// defaults:
// 用于 URL 中缺失的任何参数的值。
//
// routeHandler:
// 处理路由请求的对象。
public Route(string url, RouteValueDictionary defaults, IRouteHandler routeHandler);
//
// 摘要:
// 使用指定的 URL 模式、默认参数值、约束和处理程序类初始化 System.Web.Routing.Route 类的新实例。
//
// 参数:
// url:
// 路由的 URL 模式。
//
// defaults:
// 要在 URL 不包含所有参数时使用的值。
//
// constraints:
// 一个用于指定 URL 参数的有效值的正则表达式。
//
// routeHandler:
// 处理路由请求的对象。
public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler);
//
// 摘要:
// 使用指定的 URL 模式、默认参数值、约束、自定义值和处理程序类初始化 System.Web.Routing.Route 类的新实例。
//
// 参数:
// url:
// 路由的 URL 模式。
//
// defaults:
// 要在 URL 不包含所有参数时使用的值。
//
// constraints:
// 一个用于指定 URL 参数的有效值的正则表达式。
//
// dataTokens:
// 传递到路由处理程序但未用于确定该路由是否匹配特定 URL 模式的自定义值。这些值会传递到路由处理程序,以便用于处理请求。
//
// routeHandler:
// 处理路由请求的对象。
public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler
routeHandler);

url: 用于匹配路由和 URL 的模式。  ——就对应我们mvc中路由定义的url

defaults:他的类型为RouteValueDictionary,就是把Dictionary字典封装了一下。  ——就对应我们MVC中路由定义的defaults。但是mvc中的defaults是object类型的 (new { controller = "Home", action = "Index", id = UrlParameter.Optional }) ,源码中做了一次转化

    private static RouteValueDictionary CreateRouteValueDictionaryUncached(object values)
{
IDictionary<string, object> dictionary = values as IDictionary<string, object>;
if (dictionary != null)
{
return new RouteValueDictionary(dictionary);
}
return TypeHelper.ObjectToDictionaryUncached(values);
}

MVC中路由default转化成Route中default

routeHandler:这个比较重要类型为 IRouteHandler  它就是mvc中管道模型的handler。从这里看出mvc中的handler是从路由中注册进去的。这个下面讲到handler的时候在详细讲解。

constraints:他的类型类型为RouteValueDictionary,一个用于指定 URL 参数的有效值的正则表达式。  ——就适应我们MVC中的的constraints但是mvc中的是一个object类型(new { controller = "^H.*", action = "^Index$|^About$"},)源码中也做了一次转化,和defaults的转化方法是同一个。

dataTokens:他的类型也是RouteValueDictionary,定义:传递到路由处理程序但未用于确定该路由是否匹配特定 URL 模式的自定义值。这些值会传递到路由处理程序,以便用于处理请求。   这个直接上图其实就是MVC中的namespace(new[] { "URLsAndRoutes.AdditionalControllers" })  命名空间就是非主流。  这个直接上图。

下面使我们MVC中路由定义。

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); //忽略Hand控制器下面的所有请求 不通过路由解析
routes.IgnoreRoute("Hand/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}

2、属性

//
// 摘要:
// 获取或设置为 URL 参数指定有效值的表达式的词典。
//
// 返回结果:
// 一个包含参数名称和表达式的对象。
public RouteValueDictionary Constraints { get; set; }
//
// 摘要:
// 获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值。
//
// 返回结果:
// 一个包含自定义值的对象。
public RouteValueDictionary DataTokens { get; set; }
//
// 摘要:
// 获取或设置要在 URL 不包含所有参数时使用的值。
//
// 返回结果:
// 一个包含参数名称和默认值的对象。
public RouteValueDictionary Defaults { get; set; }
//
// 摘要:
// 获取或设置处理路由请求的对象。
//
// 返回结果:
// 处理请求的对象。
public IRouteHandler RouteHandler { get; set; }
//
// 摘要:
// 获取或设置路由的 URL 模式。
//
// 返回结果:
// 用于匹配路由和 URL 的模式。
//
// 异常:
// T:System.ArgumentException:
// 以下任一值:以 ~ 或 / 开头的值。包含 ? 字符的值。“全部捕捉”参数不在末尾。
//
// T:System.Exception:
// 没有使用分隔符或文字常量分隔 URL 分段。
public string Url { get; set; }

这些属性都在构造函数中讲了。

3、方法

//
// 摘要:
// 返回有关所请求路由的信息。
//
// 参数:
// httpContext:
// 一个对象,封装有关 HTTP 请求的信息。
//
// 返回结果:
// 一个对象,其中包含路由定义中的值。
public override RouteData GetRouteData(HttpContextBase httpContext);
//
// 摘要:
// 返回与路由关联的 URL 的相关信息。
//
// 参数:
// requestContext:
// 一个对象,封装有关所请求的路由的信息。
//
// values:
// 一个包含路由参数的对象。
//
// 返回结果:
// 一个包含与路由关联的 URL 的相关信息的对象。
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
//
// 摘要:
// 确定参数值是否与该参数的约束匹配。
//
// 参数:
// httpContext:
// 一个对象,封装有关 HTTP 请求的信息。
//
// constraint:
// 用于测试 parameterName 的正则表达式或对象。
//
// parameterName:
// 要测试的参数的名称。
//
// values:
// 要测试的值。
//
// routeDirection:
// 一个指定 URL 路由是否处理传入请求或构造 URL 的值。
//
// 返回结果:
// 如果参数值与约束匹配,则为 true;否则为 false。
//
// 异常:
// T:System.InvalidOperationException:
// constraint 不是包含正则表达式的字符串。
protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection);

两个从父类RouteBase中抽象实现的。两外一个虚方法。(虚方法好呀,可以扩展)

public override RouteData GetRouteData(HttpContextBase httpContext);

返回有关所请求路由的信息。这个RouteData就是在MVC控制器中的RouteData,参数HttpContextBase也是MVC控制器中的HttpContext。下面是源码,就是创建一个RouteData然后把Route的信息赋值给他。

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);

返回与路由关联的 URL 的相关信息。

//
// 摘要:
// 表示有关路由和虚拟路径的信息,该路由和虚拟路径是在使用 ASP.NET 路由框架生成 URL 时产生的。
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public class VirtualPathData
{
//
// 摘要:
// 初始化 System.Web.Routing.VirtualPathData 类的新实例。
//
// 参数:
// route:
// 用于生成 URL 的对象。
//
// virtualPath:
// 生成的 URL。
public VirtualPathData(RouteBase route, string virtualPath); //
// 摘要:
// 获取路由定义的自定义值集合。
//
// 返回结果:
// 路由的自定义值集合。
public RouteValueDictionary DataTokens { get; }
//
// 摘要:
// 获取或设置用于创建 URL 的路由。
//
// 返回结果:
// 一个对象,该对象表示与用于生成 URL 的参数匹配的路由。
public RouteBase Route { get; set; }
//
// 摘要:
// 获取或设置依据路由定义创建的 URL。
//
// 返回结果:
// 依据路由生成的 URL。
public string VirtualPath { get; set; }
}

VirtualPathData

参数RequestContext 这个就是HttpContext.Request.RequestContext

protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);

确定参数值是否与该参数的约束匹配。

下图中画圈的  是   定义类必须实现才能检查某 URL 参数值是否对约束有效的协定。  他是一个接口

这个接口的实现有一下几个

以FloatRouteConstraint为例。其实主要做的是正则表达式验证,以及类型TryPase转化测试。

public class FloatRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (parameterName == null)
{
throw Error.ArgumentNull("parameterName");
}
if (values == null)
{
throw Error.ArgumentNull("values");
}
object obj;
if (!values.TryGetValue(parameterName, out obj) || obj == null)
{
return false;
}
if (obj is float)
{
return true;
}
string s = Convert.ToString(obj, CultureInfo.InvariantCulture);
float num;
return float.TryParse(s, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out num);
}
}

RouteCollection

为 ASP.NET 路由操作提供路由的集合。

public class RouteCollection : Collection<RouteBase>

可以看出他是一个集合,我们用的类型一般为Route类,MVC注册路由里面使用的也是Route类型往集合中添加。

在MVC中有为期扩展了一些方法  扩展类public static class RouteCollectionExtensions(扩展方法中  在注册路由的时候把Handler也注册进去了)

RouteTable

存储应用程序的 URL 路由。

//
// 摘要:
// 存储应用程序的 URL 路由。
[TypeForwardedFrom("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
public class RouteTable
{
//
// 摘要:
// 初始化 System.Web.Routing.RouteTable 类的新实例。
public RouteTable(); //
// 摘要:
// 获取从 System.Web.Routing.RouteBase 类派生的对象的集合。
//
// 返回结果:
// 包含集合中的所有路由的对象。
public static RouteCollection Routes { get; }
}

TouteTable 里面有一个静态变量  public static RouteCollection Routes { get; }

RouteData

RouteData有别于以上几个类型,上面的类型都是在System.Web.dll程序集中的,而RouteData在System.Web.Mvc.dll中,是MVC中特有的,他在MVC的控制器中有一个变量。

//
// 摘要:
// 获取在 ASP.NET 路由确定路由是否匹配请求时,传递到路由处理程序但未使用的自定义值的集合。
//
// 返回结果:
// 一个包含自定义值的对象。
public RouteValueDictionary DataTokens { get; }
//
// 摘要:
// 获取或设置表示路由的对象。
//
// 返回结果:
// 一个表示路由定义的对象。
public RouteBase Route { get; set; }
//
// 摘要:
// 获取或设置处理所请求路由的对象。
//
// 返回结果:
// 一个处理路由请求的对象。
public IRouteHandler RouteHandler { get; set; }
//
// 摘要:
// 获取路由的 URL 参数值和默认值的集合。
//
// 返回结果:
// 一个对象,其中包含根据 URL 和默认值分析得出的值。
public RouteValueDictionary Values { get; } //
// 摘要:
// 使用指定标识符检索值。
//
// 参数:
// valueName:
// 要检索的值的键。
//
// 返回结果:
// 其键与 valueName 匹配的 System.Web.Routing.RouteData.Values 属性中的元素。
//
// 异常:
// T:System.InvalidOperationException:
// valueName 的值不存在。
public string GetRequiredString(string valueName);
路由注册过程以及Handler

1、管道模型中注册的module

控制器中写一个action


视图展示


运行显示module,以及handler

查看运行涉及到Module

2、UrlRoutingModule

定义:匹配定义的路由的 URL ,请求他是MVC框架的起点。       并且路由指定了MvcRouteHandler,最终的handler是MvcHandler。

路由的方法调用流程

上面用了很多虚方法,是为了扩展有用的。
Module注册的事件是PostResolveRequestCache。所以Handler的分配是在这个里面的,和webform不一样

源码中路由注册方法

MvcHandler到控制器

1、public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState

主要是在下图步骤3中得到控制器实例,然后控制器执行Execute方法

2、public abstract class ControllerBase : IController

在ControllerBase中执行Execute方法。但是在Execute中又执行了ExcuteCore这个抽象方法,这样又必须找他的子类中怎么实现的,通过下面Controller继承过程我们需要在找Controller类

public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer

3、这个是Controller类中的ExecuteCore执行过程。

当然这个执行过程一般的讲  是找到action名字,然后反射调用方法。复杂的讲还有请求协议(get post),方法重载等控制。

ASP.NET请求过程-从源码角度研究MVC路由、Handler、控制器的更多相关文章

  1. ASP.NET请求过程-视图如何返回客户端

    本文主要讲控制器返回ActionResult后怎么变成html到客户端的. 控制器返回的各种类型 返回所有类型的基类ActionResult // // 摘要: // 表示操作方法的结果. publi ...

  2. 服务网关zuul之二:过滤器--请求过滤执行过程(源码分析)

    Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能: 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求. 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生成 ...

  3. 【react】什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行

    壹 ❀ 引 我在[react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?一文中,介绍了虚拟dom的概念,以及react中虚拟dom的使用场景 ...

  4. ASP.NET Core MVC 源码学习:MVC 启动流程详解

    前言 在 上一篇 文章中,我们学习了 ASP.NET Core MVC 的路由模块,那么在本篇文章中,主要是对 ASP.NET Core MVC 启动流程的一个学习. ASP.NET Core 是新一 ...

  5. Android -- 带你从源码角度领悟Dagger2入门到放弃(二)

    1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...

  6. 从template到DOM(Vue.js源码角度看内部运行机制)

    写在前面 这篇文章算是对最近写的一系列Vue.js源码的文章(https://github.com/answershuto/learnVue)的总结吧,在阅读源码的过程中也确实受益匪浅,希望自己的这些 ...

  7. 从JDK源码角度看Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

  8. APIview的请求生命周期源码分析

    目录 APIview的请求生命周期源码分析 请求模块 解析模块 全局配置解析器 局部配置解析器 响应模块 异常处理模块 重写异常处理函数 渲染模块 APIview的请求生命周期源码分析 Django项 ...

  9. 从源码角度了解SpringMVC的执行流程

    目录 从源码角度了解SpringMVC的执行流程 SpringMVC介绍 源码分析思路 源码解读 几个关键接口和类 前端控制器 DispatcherServlet 结语 从源码角度了解SpringMV ...

随机推荐

  1. Connection: close

    在http1.1中request和reponse header中都有可能出现一个connection头字段,此header的含义是当client和server通信时对于长链接如何进行处理. 在http ...

  2. CSS3 clip-path & clip-path 打破矩形设计的限制

    CSS 形状模块标准1(CSS Shapes Module Level 1)这个规范打破了 WEB 中的矩形盒模型的限制,并且将网页设计提升到一个新的高度. 关于 Shapes 规范 shape-ou ...

  3. 在Kaggle免费使用GPU训练自己的神经网络

    Kaggle上有免费供大家使用的GPU计算资源,本文教你如何使用它来训练自己的神经网络. Kaggle是什么 Kaggle是一个数据建模和数据分析竞赛平台.企业和研究者可在其上发布数据,统计学者和数据 ...

  4. Oracle 11g 数据库 expdp/impdp 全量导入导出

    从一个用户导出导入到另一个用户 问题 环境:oracle 11g; redhat 6 usera是具有DBA权限,密码为usera 全量导出usera用户下的所有内容,并导入到新建的userb用户 解 ...

  5. 和重复搭建开发环境说 Bye Bye 之Vagrant

    每每新同事入职,都要在自己电脑上配置一堆环境,费神费力:每每开发测试都要重新配置开发环境,手工搭建,步骤很繁琐,极易出错. 大神在时,大神搭建,大神不在,以手抚膺坐长叹.为此,VVVVVagrant横 ...

  6. 屏幕录制 -- web前端

    前端使用html5.ffmpeg实现录屏摄像等功能 https://tong-h.github.io/2018/11/06/streamcapture/ JSCapture – 基于 HTML5 实现 ...

  7. Unity设计模式+Java设计模式,讲解+案例+PPT,一次性学会设计模式,拥抱高薪!

    一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式, ...

  8. ntpd服务

    yum -y install ntp 服务器端 [root@ip-172-31-6-148~]# vim /etc/ntp.conf ...# Use public servers from thep ...

  9. VUE导入Excel

    import FilenameOption from './components/FilenameOption' import AutoWidthOption from './components/A ...

  10. PHP判断文件大小是MB、GB、TB...

    <?php date_default_timezone_set ("PRC" ); function getFilePro($fileName){ if (!file_exi ...