Asp.Net生命周期系列三


上文講到了HttpRunTime主要做了三個事情,我們先回憶一下。

第一:雇佣了項目經理(HttpApplication)。

第二:建立了HttpModule列表,項目經理(HttpRunTime)就是按照這個工作列表去工作的。

第三:創建了Context上下文對象(包含了HttpRequest和HttpResponse兩大主要對象),並把它轉交給了HttpApplication去處理。

下面最重要的是HttpModule到底是個什么東東,HttpApplication又是怎么樣按照它的工作列表去工作的。

當一個請求到達HttpModule時,整個Asp.Net系統並沒有對這個Http請求做任何的處理,對於一個Http請求,HttpModule是這個請求的必經之路{Asp.Net內部的處理模型是一個管道流,也就是用戶發出一個Http請求一定會從HttpModule這個容器中流過},所以我們可以在Http請求真正到達請求處理中心(HttpHandler)之前,添加一些需要的信息在這個Http請求上、或者針對截獲的這個Http請求添加一些額外的工作,再或者干脆終止此次Http請求。可見HttpModule就相當於起到一個Filter過濾器的作用。

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

 

ASPNETHTTP

 

說明:
(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請求信息流進行層層的轉交動作,直到返回到 客戶端為止。

2、HttpModule的工作原理

HttpModule實現了IHttpModule接口,我們可以定義自己類實現IHttpModule接口,從而把我們自己定義的HttpModule插入到HttpModule集合中讓它成為Http請求的必經之路,以此來添加我們的控制。

asp.net自帶的HttpModule如下:具體位置在C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG文件中

  <httpModules>
            <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
            <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
            <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
            <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
            <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/>
            <add name="RoleManager" type="System.Web.Security.RoleManagerModule"/>
            <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
            <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
            <add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule"/>
            <add name="Profile" type="System.Web.Profile.ProfileModule"/>
            <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
            <add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
        </httpModules>
View Code

 

這里的每個HttpModule在一個Http請求過來時都會流過。

3、我們可以定義自己的HttpModule

要變成HttpModule就必須實現IHttpModule接口,那么我們先來看看IHttpModule接口的內部是什么樣的

 

using System;

namespace System.Web

{

    public interface IHttpModule

    {

        //   銷毀不再被HttpModule使用的資源

        void Dispose();

        // 初始化一個Module,為捕獲HttpRequest做准備

        void Init(HttpApplication context);

    }

}
View Code

 

下面是自己定義的HttpModule
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ClassLibrary1
{
    public class MyHttpModel:IHttpModule
    {

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest+=new EventHandler(context_BeginRequest);
            context.EndRequest+=new EventHandler(context_EndRequest);
        }
        public void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;
            HttpResponse response = context.Response;
            response.Write("這是自定義的HttpModel中的BeginRequest事件產生的。");
        }
        public void context_EndRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;
            HttpResponse response = context.Response;
            response.Write("這是自定義的HttpModel中的EndRequest事件產生的。");
        }
    }
}
View Code

 

置文件如下

<httpModules>
      <add name="MyHttpModel" type="ClassLibrary1.MyHttpModel,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;

namespace ClassLibrary1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write("這是Default.aspx頁面請求的內容信息。");
        }
    }
}
View Code

具體運行結果如下:

今天就寫到這里吧,文章頁有些長了,不過HttpModule還沒有介紹完呢,如果您對我的文章感興趣的話請繼續關注我的下篇,下篇我們將繼續介紹HttpModule這個東東的。

本系列:

一:Asp.Net生命周期系列一

二:Asp.Net生命周期系列二


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM