ASP.net路由原理小結

駑馬農夫發表於2017-07-20
主題 概要
Asp.net路由 Asp.net路由原理初探
編輯 時間
新建 20170714
序號 參考資料
1 http://wangqingpei557.blog.51cto.com/1009349/1312422/
2 https://github.com/aspnet/Routing(路由原始碼)

路由配置

才接觸asp.net,希望能一個專題一個專題的把問題搞明白深入些。

從最簡單的RouteConfig開始,RegisterRoutes靜態方法進行路由註冊:
這裡寫圖片描述
MapPageRoute方法是為了使Url地址與WebForm頁面實體地址隔離,MapRoute方法是MVC固定的格式。
配置好後,在Global.asax中進行註冊:
這裡寫圖片描述
注意這裡的引數,RouteTable.Routes屬性是一個RouteCollection。
這裡寫圖片描述
而注意這裡的形參routes實際傳入的是RouteTable.Routes:
這裡寫圖片描述
所以不管是WebForms的路由,還是MVC的路由,都是存放在RouteTable.Routes。

把路由資訊存放到RouteTable.Routes裡了,但是在什麼地方處理取用它呢?

UrlRoutingModule—路由物件模型的入口

這裡面的關鍵步驟是:
UrlRoutingModule繫結Application事件:

protected virtual void Init(HttpApplication application)
{
    application.PostResolveRequestCache += PostResolveRequestCache;
}

PostResolveRequestCache事件是“ASP.NET 將繞過當前事件處理程式的執行,並允許快取模組以處理從快取請求時發生”。更直白的理解就是快取模組處理從快取請求時,發生此事件。
在PostResolverRequestCache方法中,該方法呼叫了本地內部的一個同名方法:

void PostResolveRequestCache(object o, EventArgs e)
{
    var app = (HttpApplication)o;
    PostResolveRequestCache(new HttpContextWrapper(app.Context));
}

然後例項化了一個HttpContextWrapper包裝物件,傳入該同名方法:

public virtual void PostResolveRequestCache(HttpContextBase context)
{
    var rd = RouteCollection.GetRouteData(context);
    //(1)匹配RouteData物件,後面分析;
    var rc = new RequestContext(context, rd);
    //(2)封裝計算出來的RouteData物件和當前HttpRequest物件;
    IHttpHandler http = rd.RouteHandler.GetHttpHandler(rc);
    //(3)使用(1)步驟計算出來的當前RouteData物件中的RouteHander屬性獲取路由處理程式IHttpHander介面;
    context.Request.RequestContext = rc;
    context.RemapHandler(http);
}

這裡面主要分為三個步驟:
1)、根據請求,從前面註冊的路由表中,匹配到RouteData物件;
2)、根據RouteData和HttpContext封裝一個RequestContext;
3)、根據RouteData的RouteHandler屬性獲取處理程式IHttpHander介面;
這裡要注意的是RouteHandler屬性,實際上是一個IRouteHandler介面,根據依賴倒置原則,如果匹配的是MVC路由,就是MVCRouteHandler,如果匹配的是Webform就是Webform的RouteHandler,也可以自定義RouteHandler。
這裡寫圖片描述
這裡迷惑的可能是IRouteHandler 、IHttpHandler兩個介面之間的關係,IRouteHandler只有一個方法:
這裡寫圖片描述
只有實現了這個方法,才能得到正確的HttpHandler。

相關文章