前言
我們在上節講了使用ISAPI是一種重要的技術,可以讓我們擴充伺服器的功能,有兩個手段實現,一個是ISAPI擴充,一個是ISAPI過濾器,我們下面就來說說其中的這個ISAPI過濾器。
閱讀目錄
一:ISAPI篩選器
二:HttpModule
三:HttpModule的實現
四:HttpModule的運行機制
五:運行效果
六:運行效果
一:ISAPI篩選器
IIS本身是不支援動態網頁面的,也就是僅僅支援靜態.html頁面的內容,對於.asp,.aspx,.php,.java,IIS並不會處理這些標記,IIS會把這些檔案當做文本,不做處理髮送給用戶端,為瞭解決這種問題,IIS沒有這種處理能力,IIS就讓別人來處理,就是ISAPI篩選器,它是一個COM組件。
.asp有它的篩選器asp_isapi,.aspx有它的篩選器aspnet_isapi,php有它對應的篩選器。
ASP.NET服務註冊到IIS的時候,會把每個可以處理的副檔名註冊到IIS裡面(比如:*.aspx,*.ascx),這些*.aspx,*.ascx預設情況下IIS是不知道如何處理的,要是裝了ASP.NET以後,要讓IIS認識它們,但是IIS還是不認識它們,只不過是把這些*.aspx,*.ascx交給aspnet_isapi.dll來處理了,擴充好了以後,只要你請求.aspx檔案,就會自動的跳轉到專門的代碼處理當中,也就是交給aspnet_isapi.dll處理,aspnet_isapi.dll處理完了以後產生標準HTML代碼(比如:你建立了個test.aspx,在test.aspx.cs裡面的代碼是Response.Write("測試"),那麼運行後,會輸出“測試”倆字, 這就是標準HTML代碼),加入到原有的HTML代碼中(比如:你建立了個test.aspx,裡面的HTML代碼是<body></body>,這就是原有的HTML代碼),合起來就是<body>測試</body>,這就是完整的HTML代碼,最後把完整的HTML代碼返回給IIS,IIS再把HTML代碼發給瀏覽器解釋執行,說到這裡我們可以看到,IIS只認識靜態HTML代碼,對於一些動態檔案都專門交給專門的東西來處理了,.asp是asp_isapi,.aspx是aspnet_isapi等。
我們看下面這張圖安裝了ASP.NET環境以後,就把很多副檔名為其他的檔案都註冊到IIS裡面了,其中ASP.NET的環境裡需要處理的檔案都是由aspnet_isapi來處理的。
二:HttpModule
HttpModule實現了ISAPI Filter過濾器的功能,我們上面提到ISAPI擴充實現有兩個手段,一個是ISAPI擴充,一個是ISAPI過濾器,而HttpModule就是ISAPI過濾器這個手段,所以我們可以自己來寫HttpModule,它是通過繼承自System.Web.IHttpModule介面來進行處理的。
HttpModule模組是實現了System.Web.IHttpModule介面的.NET組件,這些組件通過在某些事件中註冊自身,把自己插入到HTTP請求處理管道,當這些事件發生的時候,ASP.NET調用對請求有興趣的模組,這樣該模組就能處理請求了。
三:HttpModule的實現
3.1 編寫一個類,該類實現System.Web.IHttpModule介面
3.2 實現Init方法,並且註冊需要的方法
3.3 實現註冊的方法
3.4 在web.config中註冊編寫的類
<httpModules>
<!-- add的意思是將HttpModule類添加到應用程式,name沒有講究的,type有講究的,逗號前面是命名空間.類名,逗號後面的指的是dll的檔案名稱不帶尾碼-->
<add name="myHttpModule" type="ClassLibrary.CustomHttpModule,ClassLibrary"/>
</httpModules>
四:HttpModule的運行機制
從例子看出來,一上來在Default.aspx運行之前,先運行這個模組裡的Init()方法,由於在Init()方法裡註冊了一個事件處理常式,最終會運行Init()方法裡的AuthenticateRequest()事件處理常式。
這些模組在某些事件中註冊自身,把自己插入到ASP.NET請求管道中,當某些事件發生的時候,ASP.NET調用對請求有興趣的Http模組,這樣該模組就能處理請求了。
總結一句話就是HttpModule通過對HttpApplication對象的一系列事件處理來達到對Http處理管道施加影響,這些事件在HttpModule的Init()方法中註冊,事件執行順序如下。
五:Http請求的處理過程
從中可以看出HttpMoulde貫穿了HttpHandler的前後,分別出現在了HttpHandler之前和之後。
六:運行效果
我們可以看出,無論我建立無數個頁面,只要不帶參數請求都輸出“使用者名稱或者密碼為空白,不能登陸”,儘管我的所有*.cs檔案裡任何代碼都沒有寫,這是因為 app.AuthenticateRequest += new EventHandler(this.AuthenticateRequest);這句代碼的事件是評鑑請求到達事件,是一切事件的開始。