天天看點

Web APi之Web Host消息處理管道(六)前言

我們知道Web API本身是無法提供請求-響應的機制,它是通過Web Host以及Self Host的寄宿的宿主方式來提供一個請求-響應的運作環境。二者都是将請求和響應抽象成HttpResponseMessage和HttpRequesMessage對象,并将請求HttpRequestMessage傳入到HttpMessageHandler進行處理最終将響應通過HttpResponseMessage逆向通過HttpMessageHandler傳回到用戶端,但是在其過程中,此二者在管道中的機制是不一樣的,由于在最新Web API中是以Web Host寄宿實作,是以僅本節僅讨論Web Host寄宿的實作。

Web API采用Web Host寄宿模式,其路由系統最終還是通過ASP.NET的路由系統來實作,也就是說其本質是将ASP.NET應用程式作為Web API的宿主,利用ASP.NET自身的路由系統并結合IIS來實作去持續監聽以及請求和響應的問題。

通過上述叙述知,Web API利用Web Host作為寄宿則利用UrlRoutingModel來動态映射給HttpContext中的HttpHandler是實作管道內建的核心,它會将ASP.NET中的HttpRequest對象表示的請求轉換成HttpRequestMessage對象并傳入到消息管道中,并将輸出的HttpResponseMessage寫入到HttpResponse中并最終進行響應輸出。現在最主要的問題是這個HttpHandler在Web Host模式下是怎樣實作的?請繼續往下看。

當通過Web API的配置檔案通過模闆以及限制等注冊一個HttpRoute路由對象到路由集合中時也就是将其注冊到路由表中(因為路由表中的屬性Routes存着注冊的路由的路由集合),首先會建立一個HostedHttpRoute對象,我們看看該對象的定義:

Web APi之Web Host消息處理管道(六)前言

其中最重要的是OriginalRoute屬性,照定義來看就僅僅是建立了這個對象而已,确确實實是這樣,因為該對象僅僅是起一個過渡作用,因為真正建立的對象是HttpWebRoute的Route對象,通過檢視其構造函數可知,如下:

如上紅色标記,此時将屬性OriginalRoute作為HttpWebRoute對象的引用存在HostedHttpRoute中并傳回一個Route對象。

那麼上述所說的RouteData是什麼時候生成呢?

我們再來看看這個Route對象的定義:

Web APi之Web Host消息處理管道(六)前言

當請求過來時請求URL會與注冊的路由(Route)進行比對,若比對成功,由上知,此時同時會通過GetRouteData方法生成一個 RouteData 對象,我們同時看看該RouteData的定義:

此對象中有一個比對路由Route的引用屬性,也就是目前比對成功的Route對象并且還有傳回值為IRouteHandler的屬性RouteHandler。

是以在注冊路由的過程是:

在HttpWebRoute繼承自Route類中有一個屬性RouteHandler如下:

我們通過如下HttpControllerRouteHandler的定義知,上述RouteHandler就是一個HttpControllerRouteHandler對象,因為HttpControllerRouteHandler實作了接口IRouteHandler,如下:

注意上述标記,通過GetHttpHandler方法知,在ASP.NET路由中的HttpHandler就是由HttpControllerRouteHandler對象提供的,同時我們看下該方法的定義:

看見這個方法的傳回值沒,又涉及到一個對象,其實通過HttpControllerRouteHandler中的方法獲得的HttpHandler其實是一個HttpControllerHandler對象,而整個消息處理管道則是有它來建立的。請繼續往下看!

上面說過此對象是Web Host寄宿模式下的整個管道的執行者,下面我們就來看看這個類的定義(操蛋,太長了還是就看下這個類的繼承,再叙述其他的再給代碼):

再看下其父類的定義:

簡單叙述下,HttpRouteHandler是HttpTaskAsyncHadler的子類,并且其父類為實作了IHttpAsync和IHttpHandler接口的抽象類。最主要的是HttpTaskAsyncHandler調用了實作IHttpAsyncHandler接口的BeginProcessRequest方法,并傳回一個IAsyncResult,而EndProcessRequest方法則用來執行了傳回值為IAsyncResult的BeginProcessRequest方法。

我們再來看看HttpRouteHandler的一個構造函數:

該構造函數的第一個參數就是根據路由解析得到的路由資料,第二個參數就是管道中的處理程式,實質上就是第一個HttpMessageHandler即管道頭(HttpServer)。

下面我們總結下在ASP.NET路由系統中HttpControllerHandler被建立的整個過程。請看!

下面我們實作IHttpModel接口并對照上述叙述進行編碼,如下:

Web APi之Web Host消息處理管道(六)前言

繼續閱讀