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個類關系圖

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM