Agenda
前言:
前面幾篇文章已經詳細分享解說Asp.net如何透過HttpApplication找到IHttpHandler並執行呼叫介面方法.

今天要跟大家分享上圖的最後一塊拼圖揭密並探索Asp.net MVC使用的IHttpHandler.
UrlRoutingModule-4.0
在標題已經透漏我們是透過UrlRoutingModule這個繼承IHttpModule的類別來取得IHttpHandler
有人可能會有疑問是我明明沒有註冊此HttpModule Asp.net怎麼知道的呢?
原因是這個Module是預設就載入
下圖是一般IIS預設載入的HttpModule可以看到UrlRoutingModule已經在裡面了.
另外我們也可以看applicationhost.config檔案,也可以看到UrlRoutingModule-4.0也已經在裡面了.
我們可以發現他是在System.Web.Routing這個命名空間下.
1 | <modules> |
此連結可以看到 UrlRoutingModule 原始碼
1 | protected virtual void Init(HttpApplication application) { |
前面文章有說道Init方法會在HttpApplication呼叫InitInternal方法時被呼叫.
這這裡可看到application.PostResolveRequestCache多註冊一個OnApplicationPostResolveRequestCache事件.
讓我們來看看此事件做了什麼事情
OnApplicationPostResolveRequestCache事件
OnApplicationPostResolveRequestCache方法中,利用 HttpContextWrapper轉接器模式把app.Context轉接成一個可接受HttpContextBase物件,並呼叫傳入PostResolveRequestCache方法中.
1 | private void OnApplicationPostResolveRequestCache(object sender, EventArgs e) { |
PostResolveRequestCache方法
1 | public virtual void PostResolveRequestCache(HttpContextBase context) { |
RouteCollection是一個全域路由集合,註冊使用路由(Asp.net Global.cs中我們很常看到使用).
對於此集合註冊路由,是
MVC,WebApi能運行的關鍵喔
在MVC中我們透過MapRoute擴展方法來註冊路由,其實在這個擴展方法中會建立一個Route物件並加入RouteCollection集合中.
Route物件會提供一個HttpHandler來給我們呼叫使用.
1 | routes.MapRoute( |
RouteCollection.GetRouteData(context)取得路由中匹配此次請求的路由資料,藉由此註冊進集合並繼承RouteBase抽象類別的物件
IRouteHandler取得執行HttpHandler
在routeData會有一個重要的屬性RouteHandler是繼承於IRouteHandler
這個介面只有一個方法就是回傳IHttpHandler看到這基本上就可以知道MVC的IHttpHandler是呼叫RouteHandler.GetHttpHandler回傳的物件.
1 | public interface IRouteHandler { |
後面會對於此介面有更詳細介紹
RemapHandler設置HttpContext的HttpHandler
在PostResolveRequestCache最後面幾段程式碼,是透過routeHandler.GetHttpHandler(requestContext)取得IHttpHandler,並將其設置給context
1 | IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext); |
這邊說明一下RemapHandler作用,最主要是把傳入參數handler傳給_remapHandler欄位
1 | public void RemapHandler(IHttpHandler handler) { |
_remapHandler就是RemapHandlerInstance屬性回傳的值
1 | internal IHttpHandler RemapHandlerInstance { |
我們之前有分享
MapHandlerExecutionStep,MapHttpHandler會優先讀取存在context.RemapHandlerInstance中HttpHandler如果有物件就給CallHandlerExecutionStep呼叫使用.
這邊算是比較完整圓了上一篇埋的小伏筆.
小結
今天談到我們了解到
- MVC是透過
UrlRoutingModule-4.0這個HttpModule取得HttpHandler MVC是在application.PostResolveRequestCache這個事件決定使用的HttpHandler- 路由其實是
Asp.net MVC呼叫的關鍵 - 因為在
MapHandlerExecutionStep執行前已經決定context.RemapHandlerInstance所以就不會呼叫到config設定HttpHander物件
基本上Asp.net部分已經介紹完了,接下來會進入Asp.net MVC的世界.
__此文作者__:Daniel Shih(石頭)
__此文地址__: https://isdaniel.github.io/Ithelp-day8/
__版權聲明__:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!