国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Http Module 介紹

2019-11-11 02:27:52
字體:
供稿:網(wǎng)友

引言

Http 請求處理流程 和Http Handler 介紹 這兩篇文章里,我們首先了解了Http請求在服務(wù)器端的處理流程,隨后我們知道Http請求最終會由實現(xiàn)了IHttpHandler接口的類進行處理(應(yīng)該記得Page類實現(xiàn)了IHttpHandler)。從Http 請求處理流程 一文的最后的一幅圖中可以看到,在Http請求由IHttpHandler處理之前,它需要通過一系列的Http Module;在請求處理之后,它需要再次通過一系列的Http Module,那么這些Http Module是如何組成的?用來做什么呢?本文將對Http Module作以介紹。

Http Module概述

暫時先不考慮我們自己實現(xiàn)Http Module的情況。在.Net中,Http Module 是實現(xiàn)了IHttpModule接口的程序集。IHttpModule 接口本身并沒有什么好大寫特寫的,由它的名字可以看出,它不過是一個普普通通的接口而已。實際上,我們關(guān)心的是實現(xiàn)了這些接口的類,如果我們也編寫代碼實現(xiàn)了這個接口,那么有什么用途。一般來說,我們可以將asp.net中的事件分成三個級別,最頂層是 應(yīng)用程序級事件、其次是頁面級事件、最下面是控件級事件,事件的觸發(fā)分別與 應(yīng)用程序周期、頁面周期、控件周期緊密相關(guān)。而 Http Module 的作用是與應(yīng)用程序事件 密切相關(guān)的。

我們通過Http Module在Http請求管道(Pipeline)中注冊期望對應(yīng)用程序事件做出反應(yīng)的方法,在相應(yīng)的事件觸發(fā)的時候(比如說BeginRequest事件,它在應(yīng)用程序收到一個Http請求并即將對其進行處理時觸發(fā)),便會調(diào)用Http Module注冊了的方法,實際的工作在這些方法中執(zhí)行。.Net 本身已經(jīng)有很多的Http Module,其中包括 表單驗證Module(FormsAuthenticationModule), session 狀態(tài)Module(SessionStateModule),輸出緩存Module (OutputCacheModule)等。

注冊 Http Module

在注冊我們自己編寫的 Http Module 之前,先來看看Asp.Net中已經(jīng)有的HttpModule。與 Http Handler類似,我們需要打開機器上C:/WINDOWS/Microsoft.NET/Framework/ v2.0.50727/CONFIG 目錄下的 web.config 文件。找到 <httpModules/> 結(jié)點,應(yīng)該可以看到下面的內(nèi)容:

<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" />... 略</httpModules>

我們先從結(jié)點上看,type屬性與上一節(jié)所說的http handler結(jié)點的type屬性類似,都代表了相應(yīng)的程序集。但是,與http handler 不同,module只提供了一個name屬性,沒有諸如 path這樣指定某一特定(或者用通配符 * 代表某一種類)文件的處理程序。這是與Module的特點相關(guān)的,我們知道 module 是響應(yīng)應(yīng)用程序周期中觸發(fā)的事件,對于所有提交到aspnet_isapi.dll的請求都一樣,即便請求只是像類似http://www.tracefact.net/images/logo.gif 這樣獲取一張圖片而已(對ISAPI進行過設(shè)置以后,默認aspnet_isapi.dll不接手圖片文件)。

與Http handler類似,在這冊我們自己的http module 時,假設(shè)類名為ModuleDemo,位于myNameSpace命名空間下,程序集名稱為myDll,我們只需將myDll.dll拷貝到Bin目錄下,并在站點的 web.config 文件 system.web 結(jié)點下創(chuàng)建 httpModules 結(jié)點:

<system.web>    <httpModules>       <add name="CustomModuleName" type="myNameSpace.ModuleDemo, myDll"/>    </httpModules></system.web>

type屬性由分號“,”分為兩部分,前面是命名空間及類名,也就是類型名;后面是程序集名。如果我們將代碼創(chuàng)建在App_Code目錄中,則不需要再指定程序集名。

name屬性由我們自己命名,不一定與類名相同,此處我將它命名為“CustomModuleName”。我們可以通過應(yīng)用程序(Httpapplication)的Modules屬性獲取HttpModuleCollection集合,然后通過name屬性,進一步獲取HttpModule對象。

通過name屬性,我們還可以在global.asax中文件中編寫自定義HttpModule暴露出的事件的處理程序,它采用的格式是:void ModuleName_EventName(object sender, EventArgs e)。我們將在后面做更詳細介紹。

Asp.Net 內(nèi)置的 Http Modules

下面這張表格列出了C:/WINDOWS/Microsoft.NET/Framework/ v2.0.50727/CONFIG下的Web.Config中的 Asp.Net 內(nèi)置的Http Modules 及其主要作用。

名稱類型功能
OutputCacheSystem.Web.Caching.OutputCacheModule頁面級輸出緩存
SessionSystem.Web.SessionState.SessionStateModuleSession狀態(tài)管理
WindowsAuthenticationSystem.Web.Security.WindowsAuthenticationModule用集成Windows身份驗證進行客戶端驗證
FormsAuthenticationSystem.Web.Security.FormsAuthenticationModule用基于Cookie的窗體身份驗證進行客戶端身份驗證
PassportAuthenticationSystem.Web.Security.PassportAuthenticationModule用MS護照進行客戶身份驗證
RoleManagerSystem.Web.Security.RoleManagerModule管理當(dāng)前用戶角色
UrlAuthorizationSystem.Web.Security.UrlAuthorizationModule判斷用戶是否被授權(quán)訪問某一URL
FileAuthorizationSystem.Web.Security.FileAuthorizationModule判斷用戶是否被授權(quán)訪問某一資源
AnonymousIdentificationSystem.Web.Security.AnonymousIdentificationModule管理Asp.Net應(yīng)用程序中的匿名訪問
PRofileSystem.Web.Profile.ProfileModule管理用戶檔案文件的創(chuàng)立 及相關(guān)事件
ErrorHandlerModuleSystem.Web.Mobile.ErrorHandlerModule捕捉異常,格式化錯誤提示字符,傳遞給客戶端程序

我們將在后面用編程的方式來查看它。

IHttpModule接口

看了這么多理論知識,本節(jié)將開始動手寫點程序,實現(xiàn)自己的Http Module。我們首先需要看下IHttpModule 接口,它包括下面兩個方法:

public void Init(HttpApplication context);public void Dispose();

Init():這個方法接受一個HttpApplication對象,HttpApplication代表了當(dāng)前的應(yīng)用程序,我們需要在這個方法內(nèi)注冊 HttpApplication對象暴露給客戶端的事件。可見,這個方法僅僅是用來對事件進行注冊,而實際的事件處理程序,需要我們另外寫方法。

整個過程很好理解:

當(dāng)站點第一個資源被訪問的時候,Asp.Net會創(chuàng)建HttpApplication類的實例,它代表著站點應(yīng)用程序,同時會創(chuàng)建所有在Web.Config中注冊過的Module實例。在創(chuàng)建Module實例的時候會調(diào)用Module的Init()方法。在Init()方法內(nèi),對想要作出響應(yīng)的HttpApplication暴露出的事件進行注冊。(僅僅進行方法的簡單注冊,實際的方法需要另寫)。HttpApplication在其應(yīng)用程序周期中觸發(fā)各類事件。觸發(fā)事件的時候調(diào)用Module在其Init()方法中注冊過的方法。

NOTE:如果你不了解事件注冊等相關(guān)內(nèi)容,請參閱 C#中的委托與事件 一文。

Dispose():它可以在進行垃圾回收之前進行一些清理工作。

綜上所述:實現(xiàn)一個 IHttpModule 的模板一般是這樣的:

public class ModuleDemo:IHttpModule{    public void Init(HttpApplication context) {       // 注冊HttpApplication應(yīng)用程序 BeginRequest 事件       // 也可以是其他任何HttpApplication暴露出的事件       context.BeginRequest += new EventHandler(context_BeginRequest);    }    void context_BeginRequest(object sender, EventArgs e) {       HttpApplication application = (HttpApplication)sender;       HttpContext context = application.Context;       // 做些實際的工作,HttpContext對象都獲得了,剩下的基本可以自由發(fā)揮了    }    public void Dispose() {    }}

通過Http Module向Http請求輸出流中寫入文字

本例中,我們僅用BeginRequest事件和 EndRequest 事件對 Http Module 的使用作以說明。我們通過這個范例,了解 Http Module 基本的使用方法。

首先,請創(chuàng)建一個新的站點,在App_Code目錄中添加類文件: ModuleDemo.cs:

public class ModuleDemo:IHttpModule{    // Init方法僅用于給期望的事件注冊方法    public void Init(HttpApplication context) {       context.BeginRequest += new EventHandler(context_BeginRequest);       context.EndRequest += new EventHandler(context_EndRequest);    }    // 處理BeginRequest 事件的實際代碼    void context_BeginRequest(object sender, EventArgs e) {       HttpApplication application = (HttpApplication)sender;       HttpContext context = application.Context;       context.Response.Write("<h1 style='color:#00f'>來自HttpModule 的處理,請求到達</h1><hr>");    }    // 處理EndRequest 事件的實際代碼    void context_EndRequest(object sender, EventArgs e) {       HttpApplication application = (HttpApplication)sender;       HttpContext context = application.Context;       context.Response.Write("<hr><h1 style='color:#f00'>來自HttpModule的處理,請求結(jié)束</h1>");    }           public void Dispose() {    }}

上面的代碼很簡單,它注冊了 HttpApplication實例的 BeginRequest 事件 和 EndRequest事件,事件處理方法的作用僅僅是在http請求開始和結(jié)束的時候,給http請求的輸入流中分別寫入不同的內(nèi)容。

接下來在 Web.config 的 System.web 結(jié)點中寫入以下內(nèi)容:

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

然后,打開建立站點時自動創(chuàng)建的 Default.aspx文件,在里面打幾個字,為了做區(qū)分,我輸入的是:位于.aspx頁面上的文字。然后,我們在瀏覽器中打開它,應(yīng)該會看到像這樣:

然后我們再新建一個 Default2.aspx,在瀏覽器中瀏覽,可以看到,兩個頁面的效果相同。這說明對于不同的兩個文件,http Module都起了作用,可見它確實是位于應(yīng)用程序級,而非頁面級。

現(xiàn)在,我們再打開站點中的一張圖片文件,發(fā)現(xiàn)顯示出的是一個紅叉叉,為什呢?因為Http Module 針對是http 請求,而不是某個或某一類文件,所以當(dāng)請求一張圖片的時候,我們編寫的http Module依然會起作用,將文字插入到二進制圖片中,破壞了文件格式,自然只能顯示紅叉叉了。

NOTE:如果你發(fā)現(xiàn)你的圖片顯示正常,請不要驚訝,事情是這樣的:回想一下第一節(jié)我們討論到的,對于圖片文件,由IIS直接處理,并不會交由aspnet_isapi.dll,所以,Module無法捕獲對于圖片類型文件的請求。解決方法就是在IIS中進行設(shè)置一下。    這里需要提請注意的是:如果你使用Vs2005自帶的Local Server,那么你無需對IIS進行設(shè)置,所有的不論圖片還是任何文件類型,都會交由aspnet_isapi.dll處理。

遍歷Http Module集合

現(xiàn)在,我們通過遍歷 HttpModuleCollection 集合來查看注冊給應(yīng)用程序的所有 Http Module 的名稱。

新建一個文件 RegisteredModules.aspx,在代碼后置文件中添加如下方法:

private string ShowModules() {    HttpApplication app = Context.ApplicationInstance;//獲取當(dāng)前上下文的HttpApplication環(huán)境    HttpModuleCollection moduleCollection = app.Modules;//獲取所有Module集合    // 獲取所有的 Module 名稱    string[] moduleNames = moduleCollection.AllKeys;    System.Text.StringBuilder results = new System.Text.StringBuilder();    //遍歷結(jié)果集    foreach (string name in moduleNames) {       // 獲得Module名稱       results.Append("<b style='color:#800800'>名稱:" + name + "</b><br />");        // 獲得Module類型       results.Append("類型:" + moduleCollection[name].ToString() + "<br />");    }    return results.ToString();}

然后在Page_Load方法中輸出一下:

protected void Page_Load(object sender, EventArgs e){    Response.Write(ShowModules());}

我們應(yīng)該可以看到下面這樣的畫面:

與之前列出的那張表格比較一下,可以看出是幾乎完全一致的(多了一個DefaultAuthentication)。另外注意上圖的倒數(shù)第四行,那不是我們自己定義的Module么?name為MyModule,類型為ModuleDemo。

Global.asax文件與 Http Module

早在asp時代,大家就知道這個文件了。它主要用于放置對于 應(yīng)用程序事件或者 Session事件的響應(yīng)程序。大家熟悉的有Application_Start、Application_End、Session_Start、Session_End 等。

在asp.net中,Glabal不僅可以注冊應(yīng)用程序和Session事件,還可以注冊Http Module暴露出的事件;不僅可以注冊系統(tǒng)Module的事件,也可以注冊我們自己義的Module暴露出的事件。在具體介紹之前,這里需要首先注意兩點:

在每處理一個Http請求時,應(yīng)用程序事件都會觸發(fā)一遍,但是Application_Start和 Application_End 例外,它僅在第一個資源文件被訪問時被觸發(fā)。Http Module無法注冊和響應(yīng)Session事件,對于Session_Start 和 Session_End,只能通過Glabal.asax來處理。

好了,我們現(xiàn)在修改之前 ModuleDemo 范例程序,給它像下面這樣給它添加一個事件(為了使程序簡潔一些,我做了簡化):

public class ModuleDemo : IHttpModule {    // 聲明一個事件    public event EventHandler ExposedEvent;    // Init方法僅用于給期望的事件注冊方法    public void Init(HttpApplication context) {       context.BeginRequest += new EventHandler(context_BeginRequest);    }    // 處理BeginRequest 事件的實際代碼    void context_BeginRequest(object sender, EventArgs e) {       HttpApplication application = (HttpApplication)sender;       HttpContext context = application.Context;       context.Response.Write("<h3 style='color:#00f'>來自HttpModule的處理,請求到達</h3><hr>");              OnExposedEvent(new EventArgs()); // 調(diào)用方法    }    protected overridevoid OnExposedEvent(EventArgs e) {       if (ExposedEvent != null) // 如果Global中有注冊           ExposedEvent(this, e);   // 調(diào)用注冊了的方法    }        public void Dispose() {    }}

接下來,我們在站點中創(chuàng)建一個 Global.asax 文件,在里面添加如下代碼,注意到格式是:void 模塊名_事件名(object sender, EventArgs e)。

void MyModule_ExposedEvent(object sender, EventArgs e){     Response.Write("<h3 style='color:#800800'>來自 Global.asax 的文字</h2>");}

現(xiàn)在,我們打開之前的頁面,應(yīng)該可以見到這樣,可見,我們成功的將 Glabal.asax文件與我們自己定義的Http Module所暴露出的事件 ExposedEvent 聯(lián)系到了一起:

總結(jié)

本文簡單地介紹了什么是Http Module。我們首先了解了Http Module的作用,然后查看了Asp.Net 內(nèi)置的Module,接著我們介紹了IHttpModule接口,并通過了一個簡單的范例實現(xiàn)了此接口,最后我們討論了 Http Module與 Global.asax 文件的聯(lián)系。

本文僅僅是對IHttpModule作以簡單介紹,對其更多的實際應(yīng)用,會在后續(xù)文章中補充。

希望這篇文章能給你帶來幫助!

轉(zhuǎn)自:http://www.tracefact.net/Asp-Net/Introduction-to-Http-Module.aspx


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 广平县| 长乐市| 惠水县| 庆安县| 云龙县| 墨脱县| 双辽市| 舒兰市| 视频| 澄城县| 曲阳县| 仙游县| 乌拉特前旗| 莱西市| 平塘县| 乌拉特前旗| 北流市| 东方市| 福清市| 揭阳市| 萍乡市| 靖边县| 宜丰县| 石屏县| 三河市| 汝阳县| 四川省| 信丰县| 凌海市| 天等县| 女性| 英德市| 乳山市| 佛冈县| 垦利县| 双桥区| 岳池县| 蓬安县| 新宁县| 长垣县| 东明县|