IIS/ASP.NET 管道

ASP.NET MVC 是建立在 ASP.NET 平臺(tái)上基于 MVC 模式的 Web 應(yīng)用框架,深刻理解 ASP.NET MVC 的前提是對(duì) ASP.NET 管道式設(shè)計(jì)具有深刻的認(rèn)識(shí)君躺。由于 ASP.NET Web 應(yīng)用大都寄宿于 IIS 上峭判,將兩者結(jié)合起來(lái)了解在 IIS 和 ASP.NET 管道中是如何流動(dòng)的。

IIS5.x與ASP.NET

IIS5.x 是如何處理基于 ASP.NET 資源(如.aspx棕叫、.asmx...)請(qǐng)求的呢林螃?

IIS5.x運(yùn)行在進(jìn)程 InetInfo.exe 中,該進(jìn)程寄存著一個(gè)名為 World Wide Web Publishing Service(簡(jiǎn)稱W3SVC)的 Windows 服務(wù)俺泣。W3SVC 主要負(fù)責(zé) HTTP 請(qǐng)求的監(jiān)聽(tīng)疗认、激活、管理工作進(jìn)程伏钠、加載配置(從 Metabase 中加載相關(guān)配置信息)等横漏。

IIS5.x與ASP.NET

當(dāng)檢測(cè)到某個(gè) HTTP 請(qǐng)求時(shí),IIS 先根據(jù)擴(kuò)展名判斷請(qǐng)求的是靜態(tài)資源還是動(dòng)態(tài)資源贝润。對(duì)于靜態(tài)資源 IIS 會(huì)將文件內(nèi)容直接響應(yīng)給客戶端绊茧,對(duì)于動(dòng)態(tài)資源則通過(guò)擴(kuò)展名從 IIS 的腳本映射(Script Map)中找到相應(yīng)的ISAPI 動(dòng)態(tài)鏈接庫(kù)(Dynamic Link Library, DLL)打掘。

ISAPI(Internet Server Application Programming Interface)是一套本地的(Native)Win32 API华畏,是 IIS 和其他動(dòng)態(tài) Web 應(yīng)用或平臺(tái)之間的紐帶鹏秋。

ISAPI 定義在一個(gè)動(dòng)態(tài)鏈接庫(kù)(DLL)文件中, ASP.NET ISAPI 對(duì)應(yīng)的 DLL 文件名稱為 aspnet_isapi.dll亡笑,位于 %windir%\Microsoft.NET\Framework\{version no}\中侣夷。

ISAPI 支持 ISAPI 擴(kuò)展(ISAPI Extension)和 ISAPI 篩選(ISAPI Filter),前者是真正處理 HTTP 請(qǐng)求的接口仑乌,后者則可以在 HTTP 請(qǐng)求真正被處理之前查看百拓、修改、轉(zhuǎn)發(fā)晰甚、拒絕請(qǐng)求衙传,比如 IIS 可利用 ISAPI 篩選進(jìn)行請(qǐng)求的驗(yàn)證。

若請(qǐng)求的是一個(gè)基于 ASP.NET 的資源類型厕九,如.aspx蓖捶、.asmx.svc等扁远,aspnet_isapi.dll 會(huì)被加載俊鱼,ASP.NET ISAPI 隨后會(huì)創(chuàng)建 ASP.NET 的工作進(jìn)程(若該進(jìn)程尚未啟動(dòng))。對(duì)于 IIS5.x 來(lái)說(shuō)畅买,該工作進(jìn)程為 aspnet.exe并闲。IIS 進(jìn)程與工作進(jìn)程之間通過(guò)命名管道(Named Pipes)進(jìn)行通信。

在工作進(jìn)程初始化過(guò)程中谷羞,.NET 運(yùn)行時(shí)(CLR)會(huì)被加載以構(gòu)建一個(gè)托管的環(huán)境帝火。對(duì)于某個(gè) Web 應(yīng)用的初次請(qǐng)求,CLR 會(huì)被其創(chuàng)建一個(gè)應(yīng)用程序域(Application Domain)洒宝。

在應(yīng)用程序域中购公,HTTP 運(yùn)行時(shí)(HTTP Runtime)被加載并用以創(chuàng)建相應(yīng)的應(yīng)用。寄存于 IIS5.x 的所有Web應(yīng)用都運(yùn)行在同一個(gè)進(jìn)程(工作進(jìn)程 aspnet_wp.exe)的不同應(yīng)用程序域中雁歌。

IIS6.0 與 ASP.NET

IIS5.x存在兩個(gè)方面的不足:

  • ISAPI動(dòng)態(tài)鏈接庫(kù)被加載到 InetInfo.exe 進(jìn)程中宏浩,它和工作進(jìn)程之間是一種典型的跨進(jìn)程通信方式,盡管采用命名管道靠瞎,仍會(huì)帶來(lái)性能瓶頸比庄。

解決方案:IIS6.0將ISAPI動(dòng)態(tài)鏈接庫(kù)直接加載到工作進(jìn)程中

  • ASP.NET 應(yīng)用運(yùn)行在相同進(jìn)程 aspnet_wp.exe 的不同程序域中,基于應(yīng)用程序域的隔離不能從根本上解決一個(gè)應(yīng)用程序?qū)α硪粋€(gè)程序的影響乏盐,需不同的Web應(yīng)用運(yùn)行在不同的進(jìn)程中佳窑。

解決方案:IIS6.0 加入了應(yīng)用程序池 Application Pool 的機(jī)制,為一個(gè)或多個(gè) Web 應(yīng)用創(chuàng)建一個(gè)應(yīng)用程序池父能,每個(gè)應(yīng)用程序池對(duì)應(yīng)一個(gè)獨(dú)立的工作進(jìn)程 w3wp.exe神凑,所以運(yùn)行在不同應(yīng)用程序池中的 Web 應(yīng)用提供基于進(jìn)程級(jí)別的隔離機(jī)制。

HTTP.SYS

IIS6.0 中最重要的一點(diǎn)是創(chuàng)建了一個(gè)名為 HTTP.SYS 的 HTTP 監(jiān)聽(tīng)器,HTTP.SYS 以驅(qū)動(dòng)程序的形式運(yùn)行在Windows 的內(nèi)核模式 Kernal Mode下溉委,它是 Windows TCP/IP 網(wǎng)絡(luò)子系統(tǒng)的一部分鹃唯,從結(jié)構(gòu)上看它屬于 TCP 之上的一個(gè)網(wǎng)絡(luò)驅(qū)動(dòng)程序。

嚴(yán)格地說(shuō)瓣喊,HTTP.SYS 已經(jīng)不屬于 IIS 的范疇了坡慌,所以 HTTP.SYS 的配置信息也沒(méi)有保存在 IIS 的元數(shù)據(jù)庫(kù)Metabase,而是定義在注冊(cè)表中藻三。HTTP.SYS 的注冊(cè)表項(xiàng)的路徑為HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/HTTP洪橘。

HTTP.SYS能夠帶來(lái)如下好處:

  • 持續(xù)監(jiān)聽(tīng)

由于 HTTP.SYS 是一個(gè)網(wǎng)路驅(qū)動(dòng)程序,始終處于運(yùn)行狀態(tài)棵帽,所以對(duì)于用戶會(huì)的 HTTP 請(qǐng)求能夠及時(shí)作出反應(yīng)熄求。

  • 穩(wěn)定性

HTTP.SYS 運(yùn)行在操作系統(tǒng)內(nèi)核模式下,并不執(zhí)行任何用戶代碼逗概,其本身不會(huì)受到 Web應(yīng)用抡四、工作進(jìn)程、IIS進(jìn)程的影響仗谆。

  • 內(nèi)核模式下的數(shù)據(jù)緩存

如果某個(gè)資源被頻繁請(qǐng)求,HTTP.SYS 會(huì)把響應(yīng)的內(nèi)容進(jìn)行緩存淑履,緩存的內(nèi)容可直接響應(yīng)后續(xù)的請(qǐng)求隶垮。由于這是基于內(nèi)核模式的緩存,不存在內(nèi)核模式和用戶模式的切換秘噪,響應(yīng)速度得到極大的改進(jìn)狸吞。

IIS6.0結(jié)構(gòu)

與 IIS5.x 不同,W3SVC 在 IIS6.0 中從 InetInfo.exe 進(jìn)程脫離出來(lái)指煎,對(duì)于 IIS6.0 來(lái)說(shuō)蹋偏,InetInfo.exe基本上可以看做單純的 IIS 管理進(jìn)程,運(yùn)行在另一個(gè)進(jìn)程 SvcHost.exe中至壤。不過(guò) W3SVC 的基本功能并沒(méi)有發(fā)生變化威始,只是在功能的實(shí)現(xiàn)上作出相應(yīng)的改進(jìn)。與 IIS5.x 一樣像街,元數(shù)據(jù)庫(kù) Metabase 依然存在于InetInfo.exe進(jìn)程中黎棠。

IIS6.0與ASP.NET

IIS6.0處理HTTP請(qǐng)求的流程

當(dāng)監(jiān)聽(tīng)到HTTP請(qǐng)求時(shí),HTTP.SYS 將其分發(fā)給 W3SVC镰绎,W3SVC 解析出請(qǐng)求的 URL ,并根據(jù)從 Metabase 獲取的 URL 與 Web 應(yīng)用之間的映射關(guān)系得到目標(biāo)應(yīng)用脓斩,進(jìn)而得到目標(biāo)應(yīng)用運(yùn)行的應(yīng)用程序池或工作進(jìn)程。如果工作進(jìn)程不存在或尚未創(chuàng)建或被回收畴栖,它為請(qǐng)求創(chuàng)建新的工作進(jìn)程随静。在工作進(jìn)程的初始化過(guò)程中,相應(yīng)的 ISAPI 動(dòng)態(tài)鏈接庫(kù)被加載吗讶,對(duì)于 ASP.NET 應(yīng)用來(lái)說(shuō)燎猛,被加載的 ISAPI.dllaspnet_isapi.dll恋捆。ASP.NET ISAPI 負(fù)責(zé)進(jìn)行 CLR 的加載、應(yīng)用程序域的創(chuàng)建和 Web 應(yīng)用的初始化等操作扛门。

IIS7.0與ASP.NET

IIS7.0在請(qǐng)求的監(jiān)聽(tīng)和分發(fā)機(jī)制上進(jìn)行了革新鸠信,體現(xiàn)在引入Windows進(jìn)程激活服務(wù)(Windows Process Activation Service, WAS),分流了原來(lái)IIS6.0中W3SVC承載的部分功能论寨。

IIS6.0中的W3SVC主要承載著如下三個(gè)功能:

  • HTTP請(qǐng)求接收:接收HTTP.SYS監(jiān)聽(tīng)到的HTTP請(qǐng)求
  • 配置管理:從元數(shù)據(jù)Metabase中加載配置信息對(duì)相關(guān)組件進(jìn)行配置
  • 進(jìn)程管理:創(chuàng)建星立、回收、監(jiān)控工作進(jìn)程

IIS7.0將后兩組功能實(shí)現(xiàn)到了WAS中葬凳,但接收HTTP請(qǐng)求的任務(wù)依然落在W3SVC上绰垂。WAS的引入為IIS7.0提供了對(duì)非HTTP協(xié)議的支持,通過(guò)監(jiān)聽(tīng)適配器接口 Listener Adapter Interface抽象出針對(duì)不同協(xié)議的監(jiān)聽(tīng)器火焰。具體來(lái)說(shuō)或劲装,除了專門用于監(jiān)聽(tīng)HTTP請(qǐng)求的HTTP.SYS之外,WAS利用TCP監(jiān)聽(tīng)器昌简、命名管道監(jiān)聽(tīng)器和MSMQ監(jiān)聽(tīng)器提供基于TCP占业、命名管道、MSMQ傳輸協(xié)議的監(jiān)聽(tīng)支持纯赎。

與此3種監(jiān)聽(tīng)器相對(duì)應(yīng)的是3種監(jiān)聽(tīng)適配器谦疾,它們提供監(jiān)聽(tīng)器與WAS中的監(jiān)聽(tīng)適配器接口之間的適配,從這個(gè)意義上講犬金,IIS7.0中的W3SVC相當(dāng)于HTTP.SYS的監(jiān)聽(tīng)適配器念恍。這3種非HTTP監(jiān)聽(tīng)器和監(jiān)聽(tīng)適配器定義在程序集 SMSvcHost.exe 中⊥砬辏可在目錄%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\中找到峰伙。

從程序集所在的目錄名稱可以看出,這3種監(jiān)聽(tīng)器/監(jiān)聽(tīng)適配器是為WCF設(shè)計(jì)的该默,它們以Windows服務(wù)的形式進(jìn)行工作瞳氓。雖然定義在一個(gè)程序集中。但依然可通過(guò)服務(wù)工作管理器對(duì)其進(jìn)行單獨(dú)的啟動(dòng)权均、終止顿膨、配置∵瓷蓿總的來(lái)說(shuō)恋沃,SMSvcHost.exe提供了4個(gè)重要的Windows Service。

  • NetTcpPortSharing
    為WCF提供TCP端口共享必指,即同一個(gè)監(jiān)聽(tīng)端口被多個(gè)進(jìn)程共享囊咏。
  • NetTcpActivator
    為WAS提供基于TCP的激活請(qǐng)求,包含TCP監(jiān)聽(tīng)器和對(duì)應(yīng)的監(jiān)聽(tīng)適配器。
  • NetPipeActivator
    為WAS提供基于命名管道的激活請(qǐng)求梅割,包含命名管道和對(duì)應(yīng)的監(jiān)聽(tīng)適配器霜第。
  • NetMsmqActivator
    為WAS提供基于MSMQ的激活請(qǐng)求,包含MSMQ監(jiān)聽(tīng)器和對(duì)應(yīng)的監(jiān)聽(tīng)適配器户辞。
Windows Service

IIS7.0架構(gòu)

IIS7.0與ASP.NET

無(wú)論是從W3SVC接收到的HTTP請(qǐng)求泌类,還是通過(guò)WCF提供的監(jiān)聽(tīng)適配器接收到的針對(duì)其他傳輸協(xié)議的請(qǐng)求,最終都胡被傳遞到WAS底燎。如果相應(yīng)的工作進(jìn)程刃榨,針對(duì)單個(gè)應(yīng)用程序池尚未創(chuàng)建,則WAS會(huì)創(chuàng)建工作進(jìn)程双仍。WAS在進(jìn)行請(qǐng)求處理過(guò)程中通過(guò)內(nèi)置的配置管理模塊加載相關(guān)的配置信息枢希,并對(duì)相關(guān)的組件進(jìn)行配置。

與IIS5.x和IIS6.0基于Metabase的配置信息存儲(chǔ)不同的是朱沃,IIS7.0大多將配置信息存放在XML形式的配置文件中苞轿,基本的配置存放在 applicationHost.config 中。

API.NET 集成

從IIS5.x和IIS6.0中不難發(fā)現(xiàn)逗物,IIS與ASP.NET是兩個(gè)獨(dú)立的管道 Pipeline搬卒。在各自管轄范圍內(nèi),各自具有自己的一套機(jī)制對(duì)HTTP請(qǐng)求進(jìn)行處理翎卓。兩個(gè)管道通過(guò)ISAPI實(shí)現(xiàn)連通秀睛。IIS是第一道屏障,當(dāng)對(duì)HTTP請(qǐng)求進(jìn)行必要的前期處理莲祸,如身份認(rèn)證等。IIS通過(guò)ISAPI將請(qǐng)求分發(fā)給ASP.NET管道椭迎。當(dāng)ASP.NET在自身管道范圍內(nèi)完成對(duì)HTTP請(qǐng)求的處理時(shí)锐帜,處理后的結(jié)果再返回到IIS,IIS對(duì)其進(jìn)行后期處理畜号,如日志記錄缴阎、壓縮等。之后生成HTTP回復(fù)對(duì)請(qǐng)求予以響應(yīng)简软。

IIS6.0與ASP.NET之間的橋接關(guān)系 基于IIS6.0和ASP.NET雙管道設(shè)計(jì)

從另一個(gè)角度講蛮拔,IIS運(yùn)行在非托管的環(huán)境中,而ASP.NET管道則是托管的痹升,所以說(shuō)ISAPI是連接非托管環(huán)境和托管環(huán)境的紐帶建炫。IIS5.x和IIS6.0把兩個(gè)管道進(jìn)行隔離帶來(lái)的局限的不足是:

  • 相同操作的重復(fù)執(zhí)行

IIS和ASP.NET之間具有一些重復(fù)的操作,如身份驗(yàn)證疼蛾。

  • 動(dòng)態(tài)文件與靜態(tài)文件處理的不一致

因?yàn)橹挥谢贏SP.NET 動(dòng)態(tài)文件的HTTP請(qǐng)求才能通過(guò)ASP.NET ISAPI進(jìn)入ASP.NET管道肛跌,對(duì)于靜態(tài)文件的請(qǐng)求則由IIS直接響應(yīng),那么ASP.NET管道中的一些功能將不能作用域這些基于靜態(tài)文件的請(qǐng)求,比如通過(guò)Forms認(rèn)證應(yīng)用于基于圖片文件的請(qǐng)求就做不到衍慎。

  • IIS難以擴(kuò)展

對(duì)于IIS的擴(kuò)展基本上提現(xiàn)在自定義ISAPI转唉,對(duì)于大部分人來(lái)說(shuō),這不是一件容易的事情稳捆,因?yàn)镮SAPI是基于Win32的非托管的API赠法,并非一種面向應(yīng)用的編程接口。通常希望的是諸如定義ASP.NET的HttpModule和HttpHandler一樣乔夯,托管代理的方式來(lái)擴(kuò)展IIS砖织。

對(duì)于Windows平臺(tái)下的IIS來(lái)講,ASP.NET無(wú)疑是一等公民驯嘱,IIS7.0中實(shí)現(xiàn)了兩者的集成镶苞,通過(guò)集成可獲得如下好處:

  • 允許通過(guò)本地代碼Native Code和托管代碼Managed Code兩種方式定義IIS Module

這些IIS Module注冊(cè)到IIS中形成一個(gè)通用的請(qǐng)求處理管道,由IIS Module組成的這個(gè)管道能夠處理所有的請(qǐng)求鞠评,無(wú)論請(qǐng)求基于怎樣的資源類型茂蚓。例如,可將FormAuthenticationModule提供的Forms認(rèn)證應(yīng)用到基于 .aspx剃幌、CGI和靜態(tài)文件的請(qǐng)求聋涨。

  • 將ASP.NET提供的一些強(qiáng)大的功能應(yīng)用到原來(lái)難以企及的地方

比如將ASP.NET的URL重寫(xiě)功能置于身份驗(yàn)證之前

  • 采用相同的方式去實(shí)現(xiàn)、配置负乡、檢測(cè)和支持一些服務(wù)器特性 Feature

比如Module牍白、Handler映射、定制錯(cuò)誤配置 Custom Error Configuration 等

基于IIS7.0 與 ASP.NET集成管道設(shè)計(jì)

ASP.NET 管道

以 IIS6.0為例抖棘,它的工作進(jìn)程 w3wp.exe 中會(huì)利用 aspnet_isapi.dll 加載 .NET 運(yùn)行時(shí)(如果 .NET 運(yùn)行時(shí)尚未加載)茂腥。IIS6.0引入了應(yīng)用程序池的概念,一個(gè)工作進(jìn)程對(duì)應(yīng)著一個(gè)應(yīng)用程序池切省。一個(gè)應(yīng)用程序池可以承載一個(gè)或多個(gè)Web應(yīng)用最岗,每個(gè)Web應(yīng)用映射到一個(gè)IIS虛擬目錄,與IIS5.x一樣朝捆,每個(gè)Web應(yīng)用運(yùn)行在各自的應(yīng)用程序域中般渡。

ASP.NET 處理管道

如果HTTP.SYS接收到的HTTP請(qǐng)求是對(duì)該 Web 應(yīng)用的第一次訪問(wèn),在成功加載運(yùn)行使之后芙盘,IIS會(huì)通過(guò) AppDomainFactory 為該Web應(yīng)用創(chuàng)建一個(gè)應(yīng)用程序域驯用。隨后一個(gè)特殊的運(yùn)行時(shí) IsapiRuntime 被加載。IsapiRuntime 定義在程序集 System.Web.dll中儒老,對(duì)應(yīng)的命名空間為System.Web.Hosting蝴乔, 被加載的 IsapiRuntime 會(huì)接管該HTTP請(qǐng)求。

接管 HTTP 請(qǐng)求的 IsapiRuntime 會(huì)首先創(chuàng)建一個(gè) IsapiWorkerRequest 對(duì)象來(lái)封裝當(dāng)前的HTTP請(qǐng)求驮樊,隨后將次對(duì)象傳遞給 ASP.NET 運(yùn)行時(shí) HttpRuntime淘这。從此時(shí)起剥扣, HTTP請(qǐng)求正式進(jìn)入了ASP.NET管道。HttpRuntime會(huì)根據(jù) IsapiWorkerRequest 對(duì)象創(chuàng)建用于表示當(dāng)前HTTP請(qǐng)求的上下文 Context 對(duì)象 HttpContext铝穷。

隨著 HttpContext 的創(chuàng)建钠怯,HttpRuntime 會(huì)利用 HttpApplicationFactory 創(chuàng)建新的或獲取現(xiàn)有的 HttpApplication 對(duì)象。實(shí)際上 ASP.NET 維護(hù)著一個(gè) HttpApplication 對(duì)象池曙聂, HttpApplicationFactory 從池中選取可用的 HttpApplication 用于處理 HTTP 請(qǐng)求晦炊,處理完畢后將其釋放到對(duì)象池中。HttpApplication 負(fù)責(zé)處理當(dāng)前的 HTTP 請(qǐng)求宁脊。

在 HttpApplication 初始化過(guò)程中断国,ASP.NET 會(huì)根據(jù)配置文件加載并初始化注冊(cè)的 HttpModule 對(duì)象。對(duì)于 HttpApplication 來(lái)說(shuō)榆苞,在它處理HTTP請(qǐng)求的不同階段會(huì)觸發(fā)不同的事件 Event稳衬,而HttpModule的意義在于通過(guò)注冊(cè)HttpApplication的相應(yīng)事件,將所需的操作注入整個(gè)HTTP請(qǐng)求的處理流程坐漏。ASP.NET的很多功能都是通過(guò)相應(yīng)的HttpModule實(shí)現(xiàn)的薄疚。

最終完成對(duì)HTTP請(qǐng)求的處理實(shí)現(xiàn)在HttpHandler中,不同的資源類型對(duì)應(yīng)著不同類型的HttpHandler赊琳。比如.aspx頁(yè)面對(duì)應(yīng)的HttpHandler類型為System.Web.UI.Page街夭,WCF的.svc文件對(duì)應(yīng)的HttpHandler類型為System.ServiceModel.Activation.HttpHandler

HttpApplication

HttpApplication 是整個(gè) ASP.NET 基礎(chǔ)架構(gòu)的核心躏筏,負(fù)責(zé)處理分發(fā)給它的HTTP請(qǐng)求板丽。由于一個(gè)HttpApplication對(duì)象在某個(gè)時(shí)刻只能處理一個(gè)請(qǐng)求,只有完成對(duì)某個(gè)請(qǐng)求的處理后才能用于后續(xù)請(qǐng)求的處理趁尼,所以ASP.NET采用對(duì)象池的機(jī)制來(lái)創(chuàng)建或獲取 HttpApplication 對(duì)象埃碱。

當(dāng)?shù)谝粋€(gè)請(qǐng)求抵達(dá)時(shí),ASP.NET會(huì)一次創(chuàng)建多個(gè)HttpApplication對(duì)象酥泞,并將其置于池中乃正,然后選擇其中一個(gè)對(duì)象來(lái)處理該請(qǐng)求。處理完畢后婶博,HttpApplication不會(huì)被回收,而是釋放到池中荧飞。對(duì)于后續(xù)的請(qǐng)求凡人,空閑的 HttpApplication 對(duì)象會(huì)從池中取出。如果池中所有的 HttpApplication 對(duì)象都處于繁忙的狀態(tài)叹阔,在沒(méi)有超出 HttpApplication 池最大容量的情況下挠轴,ASP.NET 會(huì)創(chuàng)建新的HttpApplication對(duì)象,否則將請(qǐng)求放入隊(duì)列等待現(xiàn)有HttpApplication的釋放耳幢。

HttpApplication 處理請(qǐng)求的整個(gè)生命周期是一個(gè)相對(duì)復(fù)雜的過(guò)程岸晦,在該過(guò)程的不同階段會(huì)觸發(fā)相應(yīng)的事件欧啤。可注冊(cè)相應(yīng)的事件启上,將處理邏輯注入到HttpApplication處理請(qǐng)求的某個(gè)階段邢隧。

HttpApplication在處理每個(gè)請(qǐng)求時(shí)觸發(fā)的事件

  • BeginRequest
    HTTP管道開(kāi)始處理請(qǐng)求時(shí),會(huì)觸發(fā)BeginRequest事件冈在。

  • AuthenticateRequest, PostAuthenticateRequest
    ASP.NET 先后觸發(fā)這兩個(gè)事件倒慧,使安全模塊對(duì)請(qǐng)求進(jìn)行身份驗(yàn)證。

  • AuthorizeRequest, PostAuthorizeRequest
    ASP.NET先后觸發(fā)這兩個(gè)事件包券,使安全模塊對(duì)請(qǐng)求進(jìn)行授權(quán)纫谅。

  • ResolveRequestCache, PostResolveRequestCache
    ASP.NET 先后觸發(fā)這兩個(gè)事件,以使緩存模塊利用緩存的內(nèi)容對(duì)請(qǐng)求直接進(jìn)行響應(yīng)(緩存模塊可將響應(yīng)內(nèi)容進(jìn)行緩存溅固,對(duì)于后續(xù)的請(qǐng)求付秕,直接將緩存的內(nèi)容返回,從而提高響應(yīng)能力侍郭。)

  • PostMapRequestHandler
    對(duì)于訪問(wèn)不同資源類型询吴,ASP.NET具有不同的HttpHandler對(duì)其進(jìn)行處理,對(duì)于每個(gè)請(qǐng)求励幼,ASP.NET會(huì)通過(guò)擴(kuò)展名選擇匹配響應(yīng)的HttpHandler類型汰寓,成功匹配后,該事件被觸發(fā)苹粟。

  • AcquireRequestState, PostAcquestRequestState
    ASP.NET先后觸發(fā)這兩個(gè)事件有滑,使?fàn)顟B(tài)管理模塊獲取基于當(dāng)前請(qǐng)求相應(yīng)的狀態(tài),如SessionState嵌削。

  • PreRequestHandlerExecute毛好、PostRequestHandlerExecute
    ASP.NET 最終通過(guò)與請(qǐng)求資源類型相對(duì)應(yīng)的 HttpHandler 實(shí)現(xiàn)對(duì)請(qǐng)求的處理,在實(shí)行 HttpHandler 前后苛秕,這兩個(gè)事件被先后觸發(fā)肌访。

  • ReleaseRequestState、PostReleaseRequestState
    ASP.NET 先后觸發(fā)這兩個(gè)事件艇劫,使?fàn)顟B(tài)管理模塊釋放基于當(dāng)前請(qǐng)求響應(yīng)的狀態(tài)吼驶。

  • UpdateRequesetCache、PostUpdateRequestCache
    ASP.NET先后觸發(fā)這兩個(gè)事件店煞,以使緩存模塊將HttpHandler處理請(qǐng)求得到的內(nèi)容得以保存到輸出緩存中蟹演。

  • LogRequest、PostLogRequest
    ASP.NET先后觸發(fā)這兩個(gè)事件為當(dāng)前請(qǐng)求進(jìn)行日志記錄

  • EndRequest 整個(gè)請(qǐng)求處理完成后顷蟀,EndRequest事件會(huì)觸發(fā)酒请。

對(duì)于一個(gè)ASP.NET應(yīng)用來(lái)說(shuō),HttpApplication派生于Global.asax文件鸣个,通過(guò)創(chuàng)建Global.asax文件對(duì)HttpApplication的請(qǐng)求處理行為進(jìn)行定制羞反。Global.asax采用一種很直接的方式實(shí)現(xiàn)了這樣的功能布朦,這種方式不是方法重寫(xiě)或事件注冊(cè),而是直接采用方法名匹配昼窗。在Global.asax中按照“Application_{Event Name}”的命名規(guī)則進(jìn)行事件注冊(cè)是趴。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace Huyoo.Backend
{
    // 注意: 有關(guān)啟用 IIS6 或 IIS7 經(jīng)典模式的說(shuō)明,
    // 請(qǐng)?jiān)L問(wèn) http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
    }
}

HttpModule

ASP.NET擁有一個(gè)具有高度的可擴(kuò)展的引擎膏秫,能處理不同資源類型的請(qǐng)求右遭,HttpModule是功不可沒(méi)的。

當(dāng)請(qǐng)求轉(zhuǎn)入ASP.NET管道時(shí)缤削,最終負(fù)責(zé)處理該請(qǐng)求的是與請(qǐng)求資源類型相匹配的HttpHandler對(duì)象窘哈,但是在HttpHandler正式工作之前。ASP.NET會(huì)先加載并初始化所有配置的HttpModule對(duì)象亭敢。HttpModule在初始化過(guò)程中滚婉,會(huì)將一些回調(diào)操作注冊(cè)到HttpApplication相應(yīng)的事件中。在HttpApplication請(qǐng)求處理生命周期中的某個(gè)階段帅刀,相應(yīng)的事件會(huì)被觸發(fā)让腹,通過(guò)HttpModule注冊(cè)的事件處理程序也得以執(zhí)行。

所有的HttpModule都實(shí)現(xiàn)了具有如下定義的System.Web.IHttpModule接口扣溺,其Init方法實(shí)現(xiàn)了針對(duì)自身的初始化骇窍。該方法接受一個(gè)HttpApplication對(duì)象,有了這個(gè)對(duì)象锥余,事件注冊(cè)就很容易了腹纳。

public interface IHttpModule
{
  void Dispose();
  void Init(HttpApplication context);
}

ASP.NET提供了很多基礎(chǔ)功能是通過(guò)相應(yīng)的HttpModule實(shí)現(xiàn)的。除了系統(tǒng)定義的HttpModule之外驱犹,可自定義HttpModule嘲恍,通過(guò) Web.config 可很容易地將其注冊(cè)到 Web 應(yīng)用中。

  • OutputCacheModule
    實(shí)現(xiàn)了輸出緩存(Output Caching)的功能
  • SessionStateModule
    在無(wú)狀態(tài)的HTTP協(xié)議上實(shí)現(xiàn)了基于會(huì)話Session的狀態(tài)保持
  • WindowsAuthenticationModule + FormsAuthenticationModule + PassportAuthenticationModule
    實(shí)現(xiàn)了Windows雄驹、Forms佃牛、Passport三種典型的身份認(rèn)證方式
  • UrlAuthorizationModule + FileAuthorizationModule
    實(shí)現(xiàn)了基于URL和文件ACL(Access Control List)的授權(quán)

HttpHandler

對(duì)于不同資源類型的請(qǐng)求,ASP.NET會(huì)加載不同的Handler來(lái)處理医舆,比如.aspx頁(yè)面與.asmx Web服務(wù)對(duì)應(yīng)的Handler是不同的俘侠。

所有的HttpHandler都實(shí)現(xiàn)了具有如下定義的接口 System.Web.IHttpHandler,定義其中的方法ProcessRequest提供了處理請(qǐng)求的實(shí)現(xiàn)蔬将。

另一個(gè)代表異步版本的HttpHandlerIHttpAsyncHandler接口繼承自IHttpHandler爷速,它通過(guò)調(diào)用BeginProcessRequest/EndProcessRequest方法以異步的方式處理請(qǐng)求。

public interface IHttpHandler
{
  void ProcessRequest(HttpContext context);
  bool IsReusable{ get; }
}
public interface IHttpAsyncHandler:IHttpHandler
{
  IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
  void EndProcessRequest(IAsyncResult result);
}

某些 HttpHandler 具有一個(gè)與之相關(guān)的HttpHandlerFactory娃胆,后者實(shí)現(xiàn)了具有如下定義的接口 System.Web.IHttpHandlerFactory,定義其中的方法GetHandler用于創(chuàng)建新的HttpHandler或獲取已經(jīng)存在的HttpHandler等曼。

public interface IHttpHandlerFactory
{
  IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTransslated);
  void ReleaseHandler(IHttpHandler handler);
}

HttpHandler和HttpHandlerFactory的類型都可以通過(guò)相同的方式配置到 Web.config中里烦。

在調(diào)用當(dāng)前HttpContext的RemapHandler方法時(shí)指定一個(gè)具體的HttpHandler對(duì)象凿蒜,是為了讓ASP.NET直接跳過(guò)默認(rèn)的HttpHandler映射操作。此外胁黑,由于這個(gè)默認(rèn)的HttpHandler映射發(fā)生在HttpApplication的PostMapRequestHandler事件觸發(fā)之前废封,所以只有在這之前調(diào)用RemapHandler方法才有意義。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丧蘸,一起剝皮案震驚了整個(gè)濱河市漂洋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌力喷,老刑警劉巖刽漂,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異弟孟,居然都是意外死亡贝咙,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門拂募,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)庭猩,“玉大人,你說(shuō)我怎么就攤上這事陈症“” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵录肯,是天一觀的道長(zhǎng)趴腋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嘁信,這世上最難降的妖魔是什么于样? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮潘靖,結(jié)果婚禮上穿剖,老公的妹妹穿的比我還像新娘。我一直安慰自己卦溢,他們只是感情好糊余,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布溪北。 她就那樣靜靜地躺著例证,像睡著了一般劈彪。 火紅的嫁衣襯著肌膚如雪墅冷。 梳的紋絲不亂的頭發(fā)上间唉,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天挟炬,我揣著相機(jī)與錄音月弛,去河邊找鬼弦叶。 笑死尊沸,一個(gè)胖子當(dāng)著我的面吹牛威沫,可吹牛的內(nèi)容都是我干的贤惯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼棒掠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼孵构!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起烟很,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颈墅,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后雾袱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體恤筛,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年谜酒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叹俏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡僻族,死狀恐怖粘驰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情述么,我是刑警寧澤蝌数,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站度秘,受9級(jí)特大地震影響顶伞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剑梳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一唆貌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垢乙,春花似錦锨咙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至钮孵,卻和暖如春骂倘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背巴席。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工历涝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓荧库,卻偏偏與公主長(zhǎng)得像诱担,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子电爹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容