ASP.net之HttpModel 和httpHandle 之一

來源:互聯網
上載者:User

標籤:tor   archive   using   處理過程   default   proc   framework   release   runtime   

HttpModule是向實作類別提供模組初始化和處置事件。當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還並沒有對這個HTTP請求做任何處理,也就是說此時對於HTTP請求來講,HttpModule是一個HTTP請求的“必經之 路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的資訊在這個HTTP請求資訊之上,或者針對截獲 的這個HTTP請求資訊作一些額外的工作,或者在某些情況下乾脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。

1、 asp.net的HTTP請求處理過程

 

 

 

 

 

 

說明: 
(1)、用戶端瀏覽器向伺服器發出一個http請求,此請求會被inetinfo.exe進程 截獲,然後轉交給aspnet_isapi.dll進程,接著它又通過Http Pipeline的管道,傳送給aspnet_wp.exe這個進程,接下來就到了.net framework的HttpRunTime處理中心,處理完畢後就發送給使用者瀏覽器。 
(2)、當一個 http請求被送入到HttpRuntime之後,這個Http請求會繼續被送入到一個被稱之為HttpApplication Factory的一個容器當中,而這個容器會給出一個HttpApplication執行個體來處理傳遞進來的http請求,而後這個Http請求會依次進入 到如下幾個容器中:HttpModule --> HttpHandler Factory --> HttpHandler。當系統內部的HttpHandler的ProcessRequest方法處理完畢之後,整個Http Request就被處理完成了,用戶端也就得到相應的東東了。 
(3)完整的http請求在asp.net framework中的處理流程: 
HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

 

也就是說一個HTTP請求在HttpModule容器的傳遞過程中,會在某一時刻(ResolveRequestCache事件)將這個HTTP請 求傳遞給HttpHandler容器。在這個事件之後,HttpModule容器會建立一個HttpHandler的入口執行個體,但是此時並沒有將HTTP 要求控制權交出,而是繼續觸發AcquireRequestState事件以及PreRequestHandlerExcute事件。在 PreRequestHandlerExcute事件之後,HttpModule視窗就會將控制權暫時交給HttpHandler容器,以便進行真正的 HTTP請求處理工作。

 

而在HttpHandler容器內部會執行ProcessRequest方法來處理HTTP請求。在容器HttpHandler處理完畢整個 HTTP請求之後,會將控制權交還給HttpModule,HttpModule則會繼續對處理完畢的HTTP請求資訊流進行層層的轉交動作,直到返回到 用戶端為止。 
PS:紅色的HttpApplication執行個體在HttpModule的Init方法中會用到。

 


(4)如果想在中途截獲一個httpRequest並做些自己的處理,就應該在HttpRuntime運行時內部來做到這一點,確切的說是在HttpModule這個容器中來實現。

2、 HttpModule工作原理

 


     負責監聽HttpRequest,同時對HttpRequest增添或者過濾掉一部分內容。也 就是說,當一個HTTP請求到達HttpModule時,整個ASP.NET Framework系統還並沒有對這個HTTP請求做任何處理,也就是說此時對於HTTP請求來講,HttpModule是一個HTTP請求的“必經之 路”,所以可以在這個HTTP請求傳遞到真正的請求處理中心(HttpHandler)之前附加一些需要的資訊在這個HTTP請求資訊之上,或者針對截獲 的這個HTTP請求資訊作一些額外的工作,或者在某些情況下乾脆終止滿足一些條件的HTTP請求,從而可以起到一個Filter過濾器的作用。 
HttpModule實現了介面IHttpModule,我們可以自訂實現該介面的類,從而取代HttpModule。 
asp.net預設的HttpModule如下:

        System.Web.SessionState.SessionStateModule;
        System.Web.Security.WindowsAuthenticationModule;
        System.Web.Security.FormsAuthenticationModule;
        System.Web.Security.PassportAuthenticationModule;
        System.Web.Security.UrlAuthorizationModule;
        System.Web.Security.FileAuthorizationModule;

 

 

3、 編寫自己的HttpModule

 

要實現HttpModule,必須實現介面IHttpModule。下面是IHttpModule介面分析:

using System;
namespace System.Web
{
    public interface IHttpModule
    {
        //   銷毀不再被HttpModule使用的資源
        void Dispose();
        // 初始化一個Module,為捕獲HttpRequest做準備
        void Init(HttpApplication context);
    }
}

 

 

 

下面是自己的HttpModule:

using System;
using System.Web;
namespace ClassLibrary1
{
    public class MyHttpModule : IHttpModule
    {
        public void Dispose() { }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Application_BeginRequest);
            context.EndRequest += new EventHandler(Application_EndRequest);
        }
        public void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;
            HttpResponse response = context.Response;
            response.Write("這是來自自訂HttpModule中有BeginRequest");
        }
        public void Application_EndRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;
            HttpResponse response = context.Response;
            response.Write("這是來自自訂HttpModule中有EndRequest");
        }
    }
}

 


web.config

    <httpModules>
      <add name="myHttpModule" type="ClassLibrary1.MyHttpModule,ClassLibrary1"/>
    </httpModules>

 

 

 

default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write("<br/><br/>來自Default.aspx頁面<br/>");
    }
}

 


 

 

4、 HttpModule內部事件機制和生命週期

 


HttpModule對HttpApplication執行個體進行處理,而HttpApplication有很多事件(對應不同的生命期),這樣就衍生出HttpModule內部事件機制和生命週期。 
(1)、HttpModule的事件

 

   
BeginRequest 指示請求處理開始
AuthenticateRequest 封裝請求身分識別驗證過程
AuthorizeRequest 封裝檢查是否能利用以前緩衝的輸出頁面處理請求的過程
ResolveRequestCache 從緩衝中得到相應時候觸發
AcquireRequestState 載入初始化Session時候觸發
PreRequestHandlerExecute 在Http請求進入HttpHandler之前觸發
PostRequestHandlerExecute 在Http請求進入HttpHandler之後觸發
ReleaseRequestState 儲存Session狀態時候觸發
UpdateRequestCache 更新緩衝資訊時觸發
EndRequest 在Http請求處理完成的時候觸發
PreSendRequestHenaders 在向用戶端發送Header之前觸發
PreSendRequestConternt 在向用戶端發送內容之前觸發

 

 

 

說明: 
a、BenginRequest和EndRequest分別是HttpModule容器最開始的和最後的事件; 
b、EndRequest之後還會觸發PreSendRequestHeaders事件和PreSendRequestContent事件,這不是在HttpModule外的兩個事件,表示HttpModule結束,即將開始向Client發送資料。

 

(2)、驗證HttpModule生命週期 
與HttpHandler的互動: 

 

說明: 
a、HttpModule容器會將HttpRequest傳遞到HttpHandler容器,這個時間點是ResolveRequestCache事件 
b、HttpModule容器會建立HttpHandler執行個體作為入口——Session從此生效 
c、觸發AcquireRequestState事件以及PreRequestHandlerExecute事件 
d、HttpModule容器便將對HttpRequest的控制權轉讓給HttpHandler容器 
e、HttpHandler容器處理HttpRequest——使用自身的ProcessRequest方法,將對其控制權又還給HttpModule容器——之後Session失效。 

 

驗證生命週期代碼:

View Code
<add name="HttpModule1" type="MyHttpModule.HttpModule1,MyHttpModule"/>
<add name="HttpModule2" type="MyHttpModule.HttpModule2,MyHttpModule"/>

 

 

 

HttpModule1和HttpModule2模仿ValidaterHttpModuleEvents編寫(除了類名改變外,事件和方法不變),不貼代碼了。運行結果如下:

 

 

 

從運行結果可以看到,在web.config檔案中引入自訂HttpModule的順序就決定了多個自訂HttpModule在處理一個HTTP請求的接管順序。

 

 

(3)、利用HttpModule實現終止此次HttpRequest請求

 

在BeginRequest事件中,使用HttpApplication.CompleteRequest()方法可以實現當滿足一定條件時終止此次HttpRequest請求

using System;
using System.Web;
namespace ClassLibrary1
{
    public class MyHttpModule : IHttpModule
    {
        public void Dispose() { }
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Application_BeginRequest);
        }
        public void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            application.CompleteRequest();
            application.Context.Response.Write("請求被終止");
        }
    }
}

 

 

 

 

說明: 
a、對於一個HttpModule,在BeginRquest中終止,但是仍然會調用EndRequest事件,以及 PreSendRequestHeaders事件和PreSendRequestContent事件。也可以說是直接跳轉到EndRequest事件,而 不會調用這期間的事件 
b、如果有兩個HttpModule,在第一個HttpModule的BeginRequest中終止,僅僅不會調用第二 個HttpModule的BeginRequest,但仍然會調用兩個EndRequest事件,以及PreSendRequestHeaders事件和 PreSendRequestContent事件。看下面的圖示:

 

 

出處:http://www.cnblogs.com/ajunForNet/archive/2013/02/26/2933439.html

ASP.net之HttpModel 和httpHandle 之一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.