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 許可協議。轉載請註明出處!