httpModules與Http模塊

httpModules是往當前應用程序添加HttpModule(http模塊)的標籤。配置節以下 程序員

<httpModules>
<add name="ModuleName"
type=".NET Class, Assembly [,Version=version number]
[,Culture=culture] [,PublicKeyToken=token]"/>
<remove... />
<clear/>
</httpModules>

   

提起httpModule不得不提一下Http請求處理流程 web

ASP.NET對請求處理的過程緩存

當請求一個*.aspx文件的時候,這個請求會被inetinfo.exe進程截獲,它判斷文件的後綴(aspx)以後,將這個請求轉交給ASPNET_ISAPI.dll,ASPNET_ISAPI.dll會經過http管道(Http PipeLine)將請求發送給ASPNET_WP.exe進程,在ASPNET_WP.exe進程中經過HttpRuntime來處理這個請求,處理完畢將結果返回客戶端。 安全

Http 管道服務器

1. HttpRuntimeHttp請求轉交給 HttpApplicationHttpApplication表明着程序員建立的Web應用程序。HttpApplication建立針對此Http請求的 HttpContext對象,這些對象包含了關於此請求的諸多其餘對象,主要是HttpRequestHttpResponseHttpSessionState等。這些對象在程序中能夠經過Page類或者Context類進行訪問。、 app

2. 接下來Http請求經過一系列Module,這些ModuleHttp請求具備徹底的控制權。這些Module能夠作一些執行某個實際工做前的事情。 學習

3. Http請求通過全部的Module以後,它會被HttpHandler處理。在這一步,執行實際的一些操做,一般也就是.aspx頁面所完成的業務邏輯。可能你會以爲在建立.aspx頁面並無體會到這一過程,可是,你必定知道,.aspx 頁面繼承自Page類,咱們看一下Page類的簽名: 網站

public class Page : TemplateControl, IHttpHandler{

    // 代碼省略

}

 

能夠看到,Page類實現了IHttpHandler接口,HttpHandler也是Http請求處理的最底層。 this

4.HttpHandler處理完之後,Http請求再一次回到Module,此時Module能夠作一些某個工做已經完成了以後的事情。 spa

從第二步到第四步能夠用下面的圖來展現

 

在http請求的處理過程當中,只能調用一個HttpHandler,但能夠調用多個HttpModule。

   

下面則詳細說說HttpModule  

HTTP 模塊是一個在每次針對應用程序發出請求時調用的程序集。HTTP 模塊做爲請求管道的一部分調用,它們可以在整個請求過程當中訪問生命週期事件。所以,HTTP 模塊使您能夠檢查傳入的請求並根據該請求進行操做。它們還使您能夠檢查傳出的響應並修改它。

ASP.NET HTTP 模塊針對全部請求調用,這與 ISAPI 篩選器相似。可是它們是用託管代碼編寫的,並且能夠與 ASP.NET 應用程序的生命週期徹底集成。能夠將自定義模塊源代碼放在應用程序的 App_Code 文件夾中,也能夠將通過編譯的自定義模塊做爲程序集放在應用程序的 Bin 文件夾中。

ASP.NET 使用模塊來實現各個應用程序功能,其中包括 Forms 身份驗證、緩存、會話狀態和客戶端腳本服務。在每種狀況下,若是這些服務處於啓用狀態,模塊會做爲請求的一部分調用,並執行在任何單一頁請求範圍以外的任務。模塊可使用應用程序事件,可能會引起可在 Global.asax 文件中處理的事件。

功能

模塊能夠訂閱多種請求管道通知。模塊能夠接收 HttpApplication 對象的事件通知。

使用場景

HTTP 模塊一般具備如下用途:

  • 安全 由於您能夠檢查傳入的請求,因此 HTTP 模塊能夠在調用請求頁、XML Web services 或處理程序以前執行自定義的身份驗證或其餘安全檢查。在以集成模式運行的 Internet 信息服務 (IIS) 7.0 中,能夠將 Forms 身份驗證擴展到應用程序中的全部內容類型。
  • 統計信息和日誌記錄 由於 HTTP 模塊是在每次請求時調用的,因此,您能夠將請求統計信息和日誌信息收集到一個集中的模塊中,而不是收集到各頁中。
  • 自定義的頁眉或頁腳 由於您能夠修改傳出響應,因此能夠在每個頁面或 XML Web services 響應中插入內容,如自定義的標頭信息。

ASP.NET中一些內置的HttpModule

名稱

類型

功能

OutputCache

System.Web.Caching.OutputCacheModule

頁面級輸出緩存

Session

System.Web.SessionState.SessionStateModule

Session狀態管理

WindowsAuthentication

System.Web.Security.WindowsAuthenticationModule

用集成Windows身份驗證進行客戶端驗證

FormsAuthentication

System.Web.Security.FormsAuthenticationModule

用基於Cookie的窗體身份驗證進行客戶端身份驗證

PassportAuthentication

System.Web.Security.PassportAuthenticationModule

MS護照進行客戶身份驗證

RoleManager

System.Web.Security.RoleManagerModule

管理當前用戶角色

UrlAuthorization

System.Web.Security.UrlAuthorizationModule

判斷用戶是否被受權訪問某一URL

FileAuthorization

System.Web.Security.FileAuthorizationModule

判斷用戶是否被受權訪問某一資源

AnonymousIdentification

System.Web.Security.AnonymousIdentificationModule

管理Asp.Net應用程序中的匿名訪問

Profile

System.Web.Profile.ProfileModule

管理用戶檔案文件的創立及相關事件

ErrorHandlerModule

System.Web.Mobile.ErrorHandlerModule

捕捉異常,格式化錯誤提示字符,傳遞給客戶端程序

   

下面摘抄了MSDN上的一個例子,自定義一個HttpModule

HttpModule必須實現接口System.Web.IHttpModule

 

namespace FastDoge.Study
{
    public class MyModule : IHttpModule
    {
        public void Dispose()
        {
            
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
            context.EndRequest +=
                (new EventHandler(this.Application_EndRequest));
        }

        private void Application_BeginRequest(Object source,
        EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.Write("<h1><font color=red>" +
                "HelloWorldModule: Beginning of Request" +
                "</font></h1><hr>");
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.Write("<hr><h1><font color=red>" +
                "HelloWorldModule: End of Request</font></h1>");
        }

    }

在 IIS 6.0 和 IIS 7.0 經典模式下運行的Web.config添加如下配置

 

<configuration>
  <system.web>
    <httpModules>
      <add name="myModule" type="FastDoge.Study.MyModule"/>
     </httpModules>
  </system.web>
</configuration>

因爲鄙人用的是IIS7集成模式,配置會不同

  <system.webServer>
    <modules>
      <add name="myModule" type="FastDoge.Study.MyModule"/>
    </modules>
  </system.webServer>

 

效果以下所示

固然網站不能是空網站,不然輸出的只是一行

<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>

的字符串。在Init方法中傳入的HttpApplication 對象能夠綁定的事件能夠參考ASP.NET 應用程序生命週期中提到的,事件一共20幾個。

在網上找了一幅圖,列出了事件觸發的順序

BeginRequest和PreRequestHandlerExecute之間的事件是在服務器執行HttpHandler處理以前觸發。

    PostRequestHandlerExecute和PreSendRequestContent之間的事件是在服務器執行Handler處理以後觸發。

但是鄙人糾結的一點在於沒發現某個ASP.NET內置的HttpModule調用了Handler。對於ASP.NET WebForm來講,每一個Page都是一個Handler。而對ASP.NET MVC來講,在以前看蔣金楠總是的著做時看到的是觸發一個UrlRoutingModule,它在OnPostResolveRequestCache事件中給HttpContext指定了一個MvcHandler。這樣就會使得HttpHandler會被調用?或許須要看一下源碼了。另外還有一個值得學習的地方就是這種模塊的添加以及往Application註冊事件的形式,使得HttpApplication具有的較好的靈活性。

在入行之初寫過一篇博客,就用到HttpModule,當時有位園友評論說能夠用Global.asax。結合當時的場景確實如此。可是二者對比起來確定有弊有利。

模塊相對於 Global.asax 文件具備以下優勢:模塊能夠進行封裝,所以能夠在建立一次後在許多不一樣的應用程序中使用。

用 Global.asax 文件的好處在於能夠處理其餘已註冊事件,如 Session_Start 和 Session_End。此外,Global.asax 文件還容許您實例化可在整個應用程序中使用的全局對象。

當您必須建立依賴應用程序事件的代碼,而且符合如下條件時,都應該使用模塊:

  • 但願在其餘應用程序中重用該模塊。
  • 但願避免將複雜代碼放在 Global.asax 文件中。
  • 該模塊應用於管道中的全部請求(僅限 IIS 7.0 集成模式)。

當您必須建立依賴應用程序事件的代碼而且不須要跨應用程序重用代碼時,應該將代碼添加到 Global.asax 文件中。

相關文章
相關標籤/搜索