路由常用对象

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. qt access 数据库

    #include <QCoreApplication> #include <QSqlDatabase> #include <QSqlQuery> #include ...

  2. R scholar和rentrez | NCBI和Google scholar文献数据挖掘

    主要会用到两个R包: rentrez: 'Entrez' in Rscholar: Analyse Citation Data from Google Scholar RISmed 包可以查询 Pub ...

  3. 通过字节码分析this关键字以及异常表的作用

    1.创建MyTest3类 public class MyTest3 { public void test(){ try { InputStream is = new FileInputStream(& ...

  4. shell脚本 获取第几行 第几列 的命令 awk sed

    例如:我们需要查看 包含 sbin的进程 中的PID号 查看当前所有包含sbin的进程 [root@fea3 ~]# ps aux | grep sbin 只过滤出所有的PID号: [root@fea ...

  5. ToggleButton 和 Switch

           界面: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...

  6. TeslaManage 2.0编译日志

    1>------ 已启动全部重新生成: 项目: TeslaManage, 配置: Debug x64 ------1> Moc'ing teslamanage.h...1> Uic' ...

  7. osgearth 编译日志

    1>------ 已启动生成: 项目: ZERO_CHECK, 配置: Debug x64 ------1> Checking Build System1> CMake does n ...

  8. C++接口的概念

    满足下面条件: 1.类中没有定义任何的成员变量 2.所有的成员函数都是公有的 3.所有的成员函数都是纯虚函数 4.接口是一种特殊的抽象类

  9. 【WebView】Android WebView中的Cookie操作

    Hybrid App(混合式应用)的开发过程中少不了与WebView的交互,在涉及到账户体系的产品中,包含了一种登录状态的传递.比如,在Native(原生)界面的登录操作,进入到Web界面时,涉及到账 ...

  10. 为什么在MySQL数据库中无法创建外键?(MyISAM和InnoDB详解)

    问题描述:为什么在MySQL数据库中不能创建外键,尝试了很多次,既没有报错,也没有显示创建成功,真实奇了怪,这是为什么呢? 问题解决:通过查找资料,每次在MySQL数据库中创建表时默认的情况是这样的: ...