ASP.NET Web API 處理架構中介紹了ASP.NET Web API主要有三層組成:宿主(hosting),消息處理管道(message handler pipeline)和控制器處理(controller handling),本篇文章主要介紹宿主(Hosting):包括ASP.NET經典管道上的Web Hosting和WCF堆棧的自宿主SelfHosting。
ASP.NET經典管道上的Web Hosting
1、ASP.NET 路由使您可以使用不必映射到網站中特定文件的 URL。 由於該 URL 不必映射到文件,因此可以使用對用戶操作進行描述因而更易於被用戶理解的 URL,路由在ASP.NET Web API上一樣有重要的位置。在ASP.NET平台上,是通過RouteTable的靜態屬性Routes添加路由到路由表里,例如下面的代碼是ASP.NET MVC項目模板默認定義的路由:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
大部分的路由邏輯是由UrlRoutingModule附加到ASP.NET 的管道事件PostResolveRequestCache,對每一個Http請求,這個模塊在路由集合中匹配符合路由規則,如果有一個匹配,則:
- 從Route Data中獲取到一個route handler
- 從Route Handler中獲取到一個實現IHttpHandler接口的Http處理程序
- 最后,當前的請求上下文映射到上述Http處理程序
因此,在ASP.NET 管道的最后將請求發送這個處理器。
2、集成Web API,當宿主與ASP.NET,Web API的配置定義在單件的HttpConfiguration對象里,通過靜態屬性GlobalConfiguration.Configuration訪問。Web API還定義了幾個RouteCollection 擴展方法,叫做 MapHttpRoute,用來定義Web APi的配置。請看下面的示例:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Routes.MapHttpRoute("default", "{controller}/{id}", new {id = UrlParameter.Optional});
// other configuration settings
上述代碼主要完成2項功能:
- 靜態屬性GlobalConfiguration.Configuration 用於獲取配置,指向全局的RouteTable.Routes 路由集合。
- 使用MapHttpRoute擴展方法添加路由配置。
通過MapHttpRoute擴展方法添加到路由集合的Route Handler是HttpControllerRouteHandler,匹配使用MapHttpRoute添加的請求,相關的Route Handler返回一個新的處理器類型 HttpControllerHandler,它實現了異步IAsyncHttpHandler 接口,這個處理器使用路由數據初始化,包含匹配的信息。
當調用HttpControllerHandler的BeginProcessRequest方法,執行下面的動作:
- 從當前的HttpContext創建一個HttpRequestMessage 實例
- 使用GlobalConfiguration.Configuration的配置創建一個HttpServer,然后把這個新的HttpRequestMessage 實例推入服務器管道。
在HttpServer獲取請求之后,它就進入了宿主處理新階段(Web API的新管道)。下面的圖總結了路由處理過程和分發到HttpServer實例(信息處理的管道)。
基於WCF堆棧的自宿主SelfHosting
上面我們介紹完了在ASP.NET上的Web宿主,接下來我們來介紹基於WCF堆棧的自宿主SelfHosting。我們先來看一段使用自宿主的代碼:
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute("default", "{controller}/{id}",
new { id = RouteParameter.Optional });
var server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
Console.WriteLine("Server is opened");
HttpSelfHostServer 繼承與HttpServer,並使用HttpSelfHostConfiguration 作為配置類,類圖結構如下:
在HttpSelfHostServer 內部使用的WCF堆棧從傳輸媒體獲取消息然后把他們推送到上層的消息處理管道。下面部分簡要介紹WCF的高層架構,Web API自宿主的特征。
WCF架構
WCF架構主要划分為2層,Channel Stack和Service Model,具體看下圖:
較低的通道堆棧層是由一堆通道和行為類似於經典的網絡協議棧。通道分為兩類:傳輸渠道和協議的渠道。負責傳輸通道由接口與傳輸介質(例如TCP,MSMQ,HTTP)(是的,我知道,HTTP不僅僅是一個傳輸協議),即由訊息的接收與傳遞。協議的信息渠道流量過程上下通過疊加。一個典型的使用案例的增加協議通道數字簽名在發送方和驗證簽名的人在接收的一面。傳輸通道,使用編碼器轉換字節流和信息輸送介質字節實例。
上層的Service Model執行消息和方法調用,所處理的人物如下:
- 把收到的消息轉換成參數序列
- 獲取到使用的服務實例
- 選擇調用的方法
- 選擇線程處理調用的方法
然而HttpSelfHostServer不使用Service Model層,相反,他直接消費了從傳輸通道堆棧獲取的消息。傳輸通道堆棧層使用Binding來組織,如下圖所示:
Binding是一個有序的Binding Element的集合,每一個元素描述一個通道或者編碼器。第一個Binding Element描述了上層通道,最后一個Binding Element描述了底層的通道,總之這是一個傳輸通道。
HttpSelfHostServer 和HttpSelfHostConfiguration 類
在內部HttpSelfHostserver.OpenAsync 方法基於HttpSelfHostConfiguration實例屬性創建和配置創建一個HttpBinding實例。然后他利用這個Binding異步創建一個WCF傳輸堆棧,他也創建一個Pump把消息推入這個堆棧,並轉換為HttpRequestMessage 實例並把新的請求推入HttpServer,下圖是消息的處理流程:
使用自宿主的時候,大多數的WCF HTTP binding 約束和設置都是可用的,在配置的內部創建的HttpBinding實例可以用2種方式創建。第一種是使用HttpSelfHostConfiguration屬性,例如MaxBufferSize 和TransferMode,這些被用於內部創建HttpBinding實例,第二種方法是創建一個HttpSelfHostConfiguration的子類,然后重寫OnConfigureBinding方法,這個方法中有機會在創建通道堆棧之前修改綁定配置。
ASP.NET WebAPI Hosting Techniques http://www.codeproject.com/Articles/555923/ASP-NET-WebAPI-Hosting-Techniques