ASP.NET基礎之HttpModule學習

最近學習WCF知識時看到有關IIS版本的知識,發現對HttpContext,HttpModule,HttpHandler的內容都不是很瞭解,這三個也是ASP.NET相對基礎的內容,晚上特意花點時間針對HttpModule的內容進行補充,文中的理論知識都是從網上多方面整理,最後的實例是本人所寫的兩個小實例,主要是針對HttpModule的運用;web

一:關於HttpModule理論知識服務器

1:HttpModule概述cookie

HttpModule是實現了IHttpModule接口的程序集。通常來講,咱們能夠將Asp.Net中的事件分紅三個級別,最頂層是 應用程序級事件、其次是頁面級事件、最下面是控件級事件,事件的觸發分別與 應用程序週期、頁面週期、控件週期緊密相關。而 Http Module 的做用是與應用程序事件密切相關的。學習

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

 

2:HttpModules做用:spa

ASP.NET請求處理過程是基於管道模型的,這個管道模型是由多個HttpModule和HttpHandler組成,當請求到達HttpModule的時候,系統尚未對這個請求真正處理,可是咱們能夠在這個請求傳遞處處理中心(HttpHandler)以前附加一些其它信息,或者截獲的這個請求並作一些額外的工做,也或者終止請求等。HttpHandler處理完請求以後,咱們能夠再在相應的HttpModule中把請求處理的結果進行再次加工返回客戶端。.net

 

3:Http模塊能夠向System.Web.HttpApplication對象註冊下面一系列事件:3d

AcquireRequestState 當ASP.NET運行時準備好接收當前HTTP請求的對話狀態的時候引起這個事件。  code

AuthenticateRequest 當ASP.NET 運行時準備驗證用戶身份的時候引起這個事件。  對象

AuthorizeRequest 當ASP.NET運行時準備受權用戶訪問資源的時候引起這個事件。     

BeginRequest 當ASP.NET運行時接收到新的HTTP請求的時候引起這個事件。     

Disposed 當ASP.NET完成HTTP請求的處理過程時引起這個事件。     

EndRequest 把響應內容發送到客戶端以前引起這個事件。     

Error 在處理HTTP請求的過程當中出現未處理異常的時候引起這個事件。     

PostRequestHandlerExecute 在HTTP處理程序結束執行的時候引起這個事件。     

PreRequestHandlerExecute 在ASP.NET開始執行HTTP請求的處理程序以前引起這個事件。在這個事件以後,ASP.NET 把該請求轉發給適當的HTTP處理程序。

PreSendRequestContent 在ASP.NET把響應內容發送到客戶端以前引起這個事件。這個事件容許咱們在內容到達客戶端以前改變響應內容。咱們可使用這個       事件給頁面輸出添加用於全部頁面的內容。例如通用菜單、頭信息或腳信息。     

PreSendRequestHeaders 在ASP.NET把HTTP響應頭信息發送給客戶端以前引起這個事件。在頭信息到達客戶端以前,這個事件容許咱們改變它的內容。咱們可使用這個事件在頭信息中添加cookie和自定義數據。     

ReleaseRequestState 當ASP.NET結束所搜有的請求處理程序執行的時候引起這個事件。     

ResolveRequestCache 咱們引起這個事件來決定是否可使用從輸出緩衝返回的內容來結束請求。這依賴於Web應用程序的輸出緩衝時怎樣設置的。     

UpdateRequestCache 當ASP.NET完成了當前的HTTP請求的處理,而且輸出內容已經準備好添加給輸出緩衝的時候,引起這個事件。這依賴於Web應用程序的輸出緩衝是如何設置的。

注意: BeginRequest和PreRequestHandlerExecute之間的事件是在服務器執行HttpHandler處理以前觸發。
 
  PostRequestHandlerExecute和PreSendRequestContent之間的事件是在服務器執行Handler處理以後觸發。

 

4:HttpModule生命週期示意圖

 

5:HttpModule實現:

HTTP模塊是實現了System.Web.IhttpModule接口的類。IHttpModule接口的聲明:
  public interface IHttpModule
  {
  void Init (HttpApplication context);
  void Dispose ();
  }
Init 方法:系統初始化的時候自動調用,這個方法容許HTTP模塊向HttpApplication 對象中的事件註冊本身的事件處理程序。
Dispose方法: 這個方法給予HTTP模塊在對象被垃圾收集以前執行清理的機會。此方法通常無需編寫代碼。

 

二:HttpModule實例(分別用兩個HttpModule來演示):

(1)第一個實例是演示實現站點全部頁面的頭部跟尾部都同時輸出相同的內容:

     步驟一:咱們新建一個類讓它繼承接口IHttpModule;並讓它實現兩個事件,用於分別輸出

using System.Web;

/// <summary>
///TestModule 的摘要說明
/// </summary>
public class TestModule:IHttpModule
{
    public TestModule()
    {
    }

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

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_StartRequest);
        context.EndRequest += new EventHandler(context_EndRequest);
    }
    /// <summary>
    /// 全部頁面頭部顯示
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void context_StartRequest(object sender, EventArgs e)
    {
        HttpApplication ha = (HttpApplication)sender;
        ha.Response.Write("頁面加載前的內容");
    }
    /// <summary>
    /// 全部頁面尾部顯示
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void context_EndRequest(object sender, EventArgs e)
    {
        HttpApplication ha = (HttpApplication)sender;
        ha.Response.Write("內容加載後的內容");
    }
}

步驟二:修改web.config 增長配置信息

    <httpModules>
      <add name="TestModule" type="TestModule,App_Code"/>
    </httpModules>

name:模塊名稱,通常是類名
type:有兩部分組成,前半部分是命名空間和類名組成的全名,後半部分是程序集名稱,若是類是直接放在App_Code文件夾中,那程序名稱是App_Code。

 步驟三:查看運行效果(其中中間是咱們當前頁的內容):

(2)第二個實例是咱們平時系統登陸功能,實例把用戶信息保存到Cookies中;在HttpModule進行統一判斷,解決之前每一個頁面或者寫個父類來進行判斷的麻煩;

        步驟一:首先咱們一樣新建一個類LoginModule繼承自IHttpModule

using System.Web;

public class LoginModule:IHttpModule
{
    public LoginModule()
    {
    }

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

    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
    }

    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication ha = (HttpApplication)sender;
        string path = ha.Context.Request.Url.Segments[2].ToString();  //得到訪問的頁面
        bool IsLogingPage = path.ToLower().Equals("login.aspx");  //比較是不是Login.aspx 是就不進入
        if (!IsLogingPage)
        {
            var CookiesDemo = ha.Context.Request.Cookies["HttpDemo"];
            if ( CookiesDemo== null)
            { 
                ha.Context.Response.Redirect("Login.aspx");
            }
        }
    }
}


步驟二:修改web.config

    <httpModules>
      <add name="LoginModule" type="LoginModule,App_Code"/>
    </httpModules>

步驟三:在登陸頁Login.aspx 實現一個針對Cookie的寫入功能;

    protected void Button1_Click(object sender, EventArgs e)
    {
        HttpCookie ck = new HttpCookie("HttpDemo");
        ck.Values.Add("UserID", "踏浪帥");
        Response.SetCookie(ck);
        Response.Redirect("Default.aspx");
    }

步驟四:在首頁Default.aspx 實現一個清除Cookie的功能,達到一個退出的功能

    protected void Button1_Click(object sender, EventArgs e)
    {
        ClearCookie("HttpDemo");
        Server.Transfer("Login.aspx");
    }

    public static void ClearCookie(string cookiename)
    {
        HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiename];
        if (cookie != null)
        {
            cookie.Expires = DateTime.Now.AddYears(-3);
            HttpContext.Current.Response.Cookies.Add(cookie);
        }
    }

效果:當沒有在Login.aspx實現登陸(寫入Cookie)而直接訪問首頁Default.aspx時系統會自動跳轉到Login.aspx;

 

但願本文對您有幫助,感謝您的閱讀;[源代碼下載]

相關文章
相關標籤/搜索