天天看點

httpModule接口

 1.編寫一個類,實作IhttpModule接口

2.實作Init 方法,并且注冊需要的方法

3.實作注冊的方法

4.實作Dispose方法,如果需要手工為類做一些清除工作,可以添加Dispose方法的實作,但這不是必需的,通常可以不為Dispose方法添加任何代碼。

5.在Web.config檔案中,注冊您編寫的類

下面是一個HttpModules的示例,在這個示例中,隻是簡單的注冊了HttpApplication 的BeginRequest 和 EndRequest事件,并且通過這些事件的實作方法,将相關的資訊列印出來。

例1:
using System;
using System.Web;
namespace MyModule
{
 public class MyModule : IHttpModule
 {
  public void Init(HttpApplication application)
  {
   application.BeginRequest += (new
EventHandler(this.Application_BeginRequest));
   application.EndRequest += (new
EventHandler(this.Application_EndRequest));
  }
      private void Application_BeginRequest(Object source, EventArgs e)
  {
   HttpApplication Application = (HttpApplication)source;
            HttpResponse Response=Application.Context.Response;
   Response.Write("<h1>Beginning of Request</h1><hr>");
  }
      private void Application_EndRequest(Object source, EventArgs e)
  {
   HttpApplication application = (HttpApplication)source;
   HttpResponse Response=Application.Context.Response;
   Response.Write("<h1>End of Request</h1><hr>");
  }
  public void Dispose()
  {
  }
 }
}      

程式的開始引用了如下名稱空間:

using System;
using System.Web;      

因為HttpApplication、HttpContext、HttpResponse等類在System.Web中定義,是以,System.Web名稱空間是必須引用的。

MyModule類實作了IhttpModule接口。在Init方法中,指明了實作BeginRequest 和EndRequest 事件的方法。在這兩個方法中,隻是簡單的分别列印了一些資訊。

下面,在Web.config檔案中注冊這個類,就可以使用這個HttpModule了,注冊的方法如下:

<configuration>
    <system.web>
        <httpModules>
            <add name=" MyModule " type=" MyModule, MyModule" />
        </httpModules>
    </system.web>
</configuration>      

現在來看一下效果。編寫一個Aspx頁面test.aspx,内容如下:

<%
Response.Write("<h1>This is the Page</h1><hr>");
%>      

運作以後的界面如圖所示:

httpModule接口

深入研究HttpModule

HttpModule通過對HttpApplication對象的一系列事件的處理來對HTTP處理管道施加影響,這些事件在HttpModule的Init方法中進行注冊,包括:

BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest      

其中部分事件同Global.asax中的事件相對應,對應關系如下:

HttpModule

Global.asax

BeginRequest

Application_BeginRequest

AuthenticateRequest

Application_AuthenticateRequest

EndRequest

Application_EndRequest

在例1中,處理了BeginRequest和EndRequest事件,其他事件的處理方式基本上類似。

同HttpHandler對應來看,這些事件,有些在HttpHandler之前發生,有些在HttpHandler處理完後發生。了解事件發生的順序非常重要,因為,伺服器端的對象在不同的時間段有着不同的表現。例子之一是Session的使用。不是所有的事件中都能對Session進行處理,而隻能在有限的幾個事件中進行處理。詳細的過程可以參考下面的HTTP Request處理生命周期圖。

httpModule接口

使用HttpModule實作權限系統

我們在開發應用系統的時候,應用系統的權限控制是非常重要的一個部分。在ASP中,要實作權限的控制是比較麻煩的事情,因為我們必須在每個需要控制權限的ASP頁面中添權重限控制代碼,進而控制客戶對頁面的通路。這樣帶來的問題,除了編寫大量重複代碼外,由于權限控制部分同業務處理部分的子產品緊密耦合在一起,對權限控制子產品的修改,往往又會帶來大量的修改工作,甚至造成大量的Bug。

是以,我們現在需要将權限控制和業務處理子產品進行解耦,使得兩個部分可以獨立開發和修改,而不會互相影響,或者,将影響減到最低。在Jsp程式中,這個目的可以通過引入一個前端控制器來實作權限過濾(關于前端控制器模式,可以參見《J2EE核心模式一書》)。在ASP.Net中,我們可以利用HttpModule實作同樣的效果。下面來看一下實作的過程。

首先,我們會建構一個權限處理系統,可以檢測某個使用者對某個子產品功能是否有通路權限(具體的結構,我想,讀者都應該接觸過這個部分的程式設計,是以不再贅述),其中,暴露給用戶端調用的權限校驗類的定義如下:

public class RightChecker
{
 public static bool HasRight(User user,Module module)
 {
  //進行權限校驗,
}
}      

然後,我們利用HttpModule編寫一個過濾器:

using System;
using System.Web;
namespace MyModule
{
 public class MyModule : IHttpModule
 {
  public void Init(HttpApplication application)
  {
 application. AcquireRequestState += (new
EventHandler(this.Application_AcquireRequestState));
  }
  private void Application_AcquireRequestState (Object source,
EventArgs e)
  {
   HttpApplication Application = (HttpApplication)source;
   User user=Application.Context.Sesseion["User"]  //擷取User
   string url=Application.Context.Request.Path;
//擷取客戶通路的頁面
   Module module= //根據url得到所在的子產品
   If(!RightChecker.HasRight(user,module))
Application.Context.Server.Transfer("ErrorPage.aspx");
//如果沒有權限,引導到錯誤處理的頁面
  }
  public void Dispose()
  {
  }
 }
}      

将這個類按照前面介紹的方法,在Web.Config中注冊後,我們的應用系統就具備權限管理的功能了。怎麼樣,比原來的方式好很多吧?

在微軟的網站上找到了篇關于HttpModule的文章發現這個技術非常的好,他能為我們的安全帶來好處.

那麼HttpModule到底是幹什麼的呢?

HttpModule是向實作類提供子產品初始化和處置事件。

首先你要實作IHttpModule接口這個接口隻有兩個方法,一個是Init方法一個Dispose方法.一看方法的名字就知道了這兩個方法一個是在加載前調用的,一個是Dispose時調用的(頁面最後處理的一個事件).

下面代碼說明了如何在所有的頁面加載之前和結束寫入一段文字:

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

/// <summary>

/// HelloWorldModule 的摘要說明

/// </summary>

public class HelloWorldModule : IHttpModule

{

public HelloWorldModule()

{

//

// TODO: 在此處添加構造函數邏輯

//

}

string str = "";

public String ModuleName

    {

get { return "HelloWorldModule"; }

    } 

public void Init(HttpApplication application)

    {

//注冊頁面請求開始和結束事件

        application.BeginRequest +=

            (new EventHandler(this.Application_BeginRequest));

        application.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>"+

        application.Request.QueryString.Count.ToString());

    }

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>");

    }

public void Dispose()

    {

    }

}

在web.config增加下面配置:

<httpModules>

<add name="HelloWorldModule" type="HelloWorldModule"/>

</httpModules>

上面是個小例子.那我們可以在這裡做多少件事情呢?看下面的表就可以得出結論.

事件

說明

BeginRequest

訓示請求處理開始。

AuthenticateRequest

PostAuthenticateRequest

封裝請求身份驗證過程。

AuthorizeRequest

PostAuthorizeRequest

封裝請求授權過程。

ResolveRequestCache

PostResolveRequestCache

封裝檢查是否能利用以前緩存的輸出頁面處理請求的過程。

PostMapRequestHandler

訓示已發現用于處理請求的 HTTP 處理程式。

AcquireRequestState

PostAcquireRequestState

封裝對請求會話狀态的檢索。

PostRequestHandlerExecute

訓示用于處理請求的 HTTP 處理程式已執行。

ReleaseRequestState

PostReleaseRequestState

封裝對請求會話狀态的釋出。

UpdateRequestCache

PostUpdateRequestCache

封裝檢查是否應對請求的資源的輸出進行緩存以備今後重複使用的過程。

EndRequest

訓示請求處理結束。

我們可以根據相應的事件來進行處理.做了這麼長時間才發現你沒想到的微軟都替你想到了.

在httpModule中到底要做什麼?我根據一個朋友的文章寫了個根據配置檔案來驗證頁面的連接配接字元串的傳參個數和傳參的内容是否符合标準的例子.

還有個朋友給我說了,這個可以用來修改跳轉Url的改寫.

在CommunityServer中還用httpModule做了當異常處理的時候進行程式異常的頁面列印的操作.

AuthenticateRequest 請求身份驗證和AuthorizeRequest請求授權過程的操作.

繼續閱讀