這篇文章是從我的 github 博客 lxconan.github.io 導入的。
這是這個系列的第三篇了。前兩篇文章請參見:
這一篇仍然是原理上的東西,不涉及代碼。我保證從下一篇開始,我們就開始寫代碼了。所以還請忍耐。
ASP.NET 的請求處理流程
在這篇文章中,我們討論的問題是 ASP.NET 對 HTTP 請求的處理流程。但是這個流程并不止限于 ASP.NET。許許多多的 Web Server 都是采用了相似的處理流程。這個流程就像是張三在上課的時候給他的好朋友(或者死對頭)(我們叫他:趙六)傳紙條。首先我假定張三很尊重老師的,不想傷害他脆弱的心靈,于是他無法把紙條直接傳到趙六的手中,他必須先把紙條交給離他最近的同學手中,然后依次傳遞。我們不妨假定這個過程必須經過這幾個人:
張三 --> 李四 --> 王五 --> 趙六
那么不難想到,紙條回來的路徑也需要依次反向的經過相同的人。也就是
趙六 --> 王五 --> 李四 --> 張三
那么傳紙條開始,首先張三寫了一張紙條,其內容是:(少兒不宜,故隱去)。紙條送到了李四的手中,李四是一個有理想有道德的青年,于是拒絕繼續傳遞下去。張三無奈,只得又寫了一張新的。其內容是:“下課后是否去一起吃飯?”。紙條送到了李四的手中,李四看后把紙條遞給了王五;王五看后將紙條遞給了趙六。趙六看后,欣然寫到:“好滴”,又把紙條交到了王五手中;王五接到紙條不覺有些心動,于是在紙條上也添了一筆:“我也去!”,就把紙條交給了李四;李四直接將紙條傳回張三手中,于是張三看到了如下的內容:“好滴。我也去(王五)”。
我們不妨將張三的行為視為張三向趙六發出的請求。而在請求傳遞的過程中經過了李四和王五。整個過程一共涉及到了兩種角色:第一種角色是趙六,他是請求到達的終結點,也是創建響應的人;而第二種角色就是李四和王五,他們在整個過程中都可以看到請求和響應的內容,并可以對請求或者響應進行過濾或者更改。
在 ASP.NET 中,這兩種角色分別稱之為:Http Handler
以及 Http Module
。Http Handler
作為 Request 處理的終結點存在,并負責處理請求以及生成響應。幾乎所有的高級 Web 特性,例如頁面的生成、MVC 都是 Http Handler
。而相應的 Http Module
作為請求傳遞的中間環節,主要對 Request/Response 進行過濾和修飾。常見的任務例如身份驗證,Session 管理都是使用 Http Module
進行處理的。
不難理解,每一個 Request 最多只可能有一個 Http Handler
對其進行處理;而每一個 Request 可能會有多個 Http Module
對其進行過濾或者修飾。
在 ASP.NET 中,Http Handler
實現了 IHttpHandler
接口而 Http Module
實現了 IHttpModule
接口。
觀察 Http Handler 和 Http Module
如何觀察我們的 Web App 搭建了怎樣的處理流程呢?
在 IIS 中觀察
第一種方式是在 IIS 中觀察,這種方式非常簡單實用。首先打開 IIS 管理器,選擇需要觀察的 Web App 或者某一個虛擬目錄。之后,在右側的“處理程序映射”中可以看到所有啟用了的 Http Handler
。例如,我的 Web App 啟用了如下的 Http Handler
:
- 對于
\*
類型的請求,使用System.Web.Handlers.TransferRequestHandler
進行處理(這個Http handler
也是 ASP.NET MVC 的基礎); - 對于
*.aspx
類型的請求,使用System.Web.UI.PageHandlerFactory
進行處理(這個Http handler
是 WebForm 的基礎); - 對于
*.cshtml
類型的請求,使用System.Web.HttpForbiddenHandler
進行處理(因為客戶端是不允許訪問服務端代碼的); - ……
至于 Http Module
,可以在 “模塊” 中進行觀察。在“分組依據”中選擇“托管模塊”就可以觀察到 ASP.NET 注冊的 Http Module
了。
在 Powershell 中觀察
第二種方式是在 Powershell 中使用 IIS Extension 進行觀察。這個非常符合我們的胃口,也為 Automation 提供了可能。在觀察之前,請確認你已經安裝了 Powershell 的 WebAdministration 模塊。然后以管理員身份啟動 Powershell,在 Powershell 中進行如下輸入:
PS C:\> IIS:
PS IIS:\> cd Sites
PS IIS:\Sites> cd Default # Suppose we have a website named 'Default'
PS IIS:\Sites\Default>
此時我們就進入了 Default Website 的虛擬路徑。我們可以使用 Get-WebHandler
查看當前虛擬路徑下的 Http handler
設置。
PS IIS:\Sites\Default> Get-WebHandler
Name Path Verb Modules
---- ---- ---- -------
WebDAV * PROPFIND,PROPPATCH,MKCOL,P... WebDAVModule
ISAPI-dll *.dll * IsapiModule
AXD-ISAPI-4.0_64bit *.axd GET,HEAD,POST,DEBUG IsapiModule
PageHandlerFactory-ISAPI-4... *.aspx GET,HEAD,POST,DEBUG IsapiModule
SimpleHandlerFactory-ISAPI... *.ashx GET,HEAD,POST,DEBUG IsapiModule
WebServiceHandlerFactory-I... *.asmx GET,HEAD,POST,DEBUG IsapiModule
HttpRemotingHandlerFactory... *.rem GET,HEAD,POST,DEBUG IsapiModule
HttpRemotingHandlerFactory... *.soap GET,HEAD,POST,DEBUG IsapiModule
... ...
為了查看 ASP.NET 注冊的 Http Module
我們可以使用如下的命令:Get-WebManagedModule
PS IIS:\Sites\Default> Get-WebManagedModule
Name Precondition Type
---- ------------ ----
UrlRoutingModule-4.0 managedHandler,runtimeVersionv4.0 System.Web.Routing.Url...
ScriptModule-4.0 managedHandler,runtimeVersionv4.0 System.Web.Handlers.Sc...
OutputCache managedHandler System.Web.Caching.Out...
Session managedHandler System.Web.SessionStat...
WindowsAuthentication managedHandler System.Web.Security.Wi...
FormsAuthentication managedHandler System.Web.Security.Fo...
DefaultAuthentication managedHandler System.Web.Security.De...
RoleManager managedHandler System.Web.Security.Ro...
UrlAuthorization managedHandler System.Web.Security.Ur...
FileAuthorization managedHandler System.Web.Security.Fi...
AnonymousIdentification managedHandler System.Web.Security.An...
Profile managedHandler System.Web.Profile.Pro...
UrlMappingsModule managedHandler System.Web.UrlMappings...
在 web.config 文件中觀察
在上一篇中,我們介紹了 web.config 文件是有一種繼承體系的。那么我們可以在這個體系涉及的各個文件中查找 Http handler
以及 Http Module
的配置。
Http handler
的配置在 .config
文件的 <system.webServer>
的 <handlers>
元素下。例如,我們可以在 IIS 的 applicationHost.config 文件中發現如下的 HTTP handler
的映射信息:
<system.webServer>
<handlers accessPolicy="Read, Script">
<add
name="ExtensionlessUrlHandler-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
... ...
</handlers>
</system.webServer>
而 Http Module
是配置在 <system.webServer>
的 <modules>
下。例如,我們可以在 IIS 的 applicationHost.config 文件中發現如下的 Http Module
信息:
<system.webServer>
<modules>
... ...
<add
name="OutputCache"
type="System.Web.Caching.OutputCacheModule"
preCondition="managedHandler" />
... ...
</modules>
</system.webServer>
這一篇的介紹就到這里,從下一篇開始我們將開始盡可能的構造自動化部署腳本。
文章列表