ASP.NET MVC 请求流程:Route

引用:https://www.cnblogs.com/zxj159/p/4112606.html#undefined

1.RouteTable

  RouteTable翻译过来的意思就是路由表,一个Web应用程序具有一个全局的路由表,该路由表通过System.Web.Routiing.RouteTable的静态只读属性Routes表示,该类型返回一个类型为System.Web.Routingg.RouteCollection的集合。

  RouteTable类十分的简单,如下所示

复制代码
    public class RouteTable
    {
        private static RouteCollection _instance = new RouteCollection(); //返回一个静态只读的RouteCollection类型实例 public static RouteCollection Routes { get { return RouteTable._instance; } } public RouteTable() { } }
复制代码

  现在我们来看一下运行时的状态

复制代码
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); //断点1  } }
复制代码

  下图就是当断点处于断点1时,RouteTable的状态 ,我们在这里可以很清楚的看到现在Routes属性所包含的路由条数为0,不急我们继续向下走。

2.RouteCollection

  看到名称就不难猜到,这个应该是表示路由集合,我们先来看看这个类里面有什么新奇玩意。

复制代码
public class RouteCollection : Collection<RouteBase>
    {
        //其余省略

        //是否添加首尾斜杠.默认值为 false. public bool AppendTrailingSlash { get; set; } //是否将 URL 转换为小写.默认值为 false. public bool LowercaseUrls { get; set; } //是否应处理与现有文件匹配的 URL.默认值为 false. public bool RouteExistingFiles { get; set; } //获取路由信息 public RouteData GetRouteData(HttpContextBase httpContext); //获取虚拟路径信息 public VirtualPathData GetVirtualPath(RequestContext requestContext, string name, RouteValueDictionary values); //忽略路由URL和相关约束 public void Ignore(string url, object constraints); //添加路由 public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens); }
复制代码

  稍微了解了这个类是用来干什么的,那么我们就要接着上面的程序向下走了,当然先介绍以下RouteBase和Route类吧

3.RouteBase,Route

  在上图中我们看到了RouteBase,Route类,来说一下它们是什么吧。

  RouteBase

  RouteBase是Route类的父类,我们还是来看下它的类结构吧

View Code

  RouteURL模版模式的路由匹配规则就定义在Route中,看下类结构吧

View Code

  介绍完RouteBase和Route类后,我们的代码继续向下走

复制代码
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { controller = "^H.*" }, namespaces: new[] { "SimpleMVC" } ); }
复制代码

  看上面一段代码,我们发现RouteCollection实例有两个方法,但是System.Web.Routing.RouteCollection类中并没有这两个方法,那这个怎么实现的呢?

  我们在IgnoreRoute上转到定义看下,发现我们跳转到了System.Web.Mvc.RouteCollectionExtensions这个路由集合扩展类了,在看下这个方法

    public static void IgnoreRoute(this RouteCollection routes, string url) { routes.IgnoreRoute(url, null); }

  一看恍然大悟,原来是通过扩展方法,感叹下扩展方法原来是可以这么用的。

  好了,那么routes.MapRoute也肯定是通过扩展方法注入的。那我们就看下route.MaoRoute是实现的。

复制代码
    public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } // MvcRouteHandler 是请求进入时使用MVC路由关键 Route route = new Route(url, new MvcRouteHandler()) { // 存储为路由变量定义的默认值 Defaults = RouteCollectionExtensions.CreateRouteValueDictionaryUncached(defaults), // 存储路由约束 Constraints = RouteCollectionExtensions.CreateRouteValueDictionaryUncached(constraints), // 存储额外变量,但不会参与针对请求地址的匹配工作,比如Namespaces DataTokens = new RouteValueDictionary() }; ConstraintValidation.Validate(route); if (namespaces != null && namespaces.Length > 0) { route.DataTokens["Namespaces"] = namespaces; } // 向RouteCollection中添加路由  routes.Add(name, route); // 返回该路由 return route; }
复制代码

  好了,我们大概已经了解这两个扩展方法的作用了,下面我们来看看它们在运行时的状态

复制代码
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, constraints: new { controller = "^H.*" }, namespaces: new[] { "SimpleMVC" }  );// 断点2 }
复制代码

  我们看看当断点停留在断点2处时,类里面的状态是怎样的?如下图

  我们可以很清楚的看到RouteCollection实例包含两条由规则,这两条路由规则都是继承自System.Web.Routing.RouteBase,第一条是我们定义为忽略的路由,类型是System.Web.Mvc.RouteCollectionExtensions.IgnoreRouteInternal,该类型继承子System.Web.Routing.Route,第二条则是我们定义的有效的路由,类型是System.Web.Routing.Route。

  我们在深入看下第二条有效的路由信息

  通过上图,可以非常明显的看出,哪些数据存储到了哪些属性里面,可以有个直观的理解。

4.关系

  好了,我们的程序需要继续向下走,执行完RegisterRoutes方法后,我们又回到了Application_Start方法。

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes); // 断点1
        } // 断点3

  我们在断点3出看下各类的状态,总结下RouteTable,RouteCollection,RouteBase,Route4个类之间的关系,如下图所示

  下面是一张RouteTable,RouteCollection,RouteBase,Route4个类关系图

  

猜你喜欢

转载自www.cnblogs.com/zqyhave/p/9019797.html