乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      HttpModule與HttpHandler詳解

       kittywei 2011-05-05

        ASP.NET對請求處理的過程:

        當(dāng)請求一個*.aspx文件的時候,這個請求會被inetinfo.exe進(jìn)程截獲,它判斷文件的后綴(aspx)之后,將這個請求轉(zhuǎn)交給 ASPNET_ISAPI.dll,ASPNET_ISAPI.dll會通過http管道(Http PipeLine)將請求發(fā)送給ASPNET_WP.exe進(jìn)程,在ASPNET_WP.exe進(jìn)程中通過HttpRuntime來處理這個請求,處理完畢將結(jié)果返回客戶端。

        inetinfo.exe進(jìn)程:是www服務(wù)的進(jìn)程,IIS服務(wù)和ASPNET_ISAPI.DLL都寄存在此進(jìn)程中。

        ASPNET_ISAPI.DLL:是處理.aspx文件的win32組件。其實(shí)IIS服務(wù)器是只能識別.html文件的,當(dāng)IIS服務(wù)器發(fā)現(xiàn)被請求的文件是.aspx文件時,IIS服務(wù)器將其交給aspnet_isapi.dll來處理。

        aspnet_wp.exe進(jìn)程:ASP.NET框架進(jìn)程,提供.net運(yùn)行的托管環(huán)境,.net的CLR(公共語言運(yùn)行時)就是寄存在此進(jìn)程中。

        ASP.NET Framework處理一個Http Request的流程:

        HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

        ASP.NET請求處理過程是基于管道模型的,這個管道模型是由多個HttpModule和HttpHandler組成,ASP.NET 把http請求依次傳遞給管道中各個HttpModule,最終被HttpHandler處理,處理完成后,再次經(jīng)過管道中的HTTP模塊,把結(jié)果返回給客戶端。我們可以在每個HttpModule中都可以干預(yù)請求的處理過程。

        注意:在http請求的處理過程中,只能調(diào)用一個HttpHandler,但可以調(diào)用多個HttpModule。

        當(dāng)請求到達(dá)HttpModule的時候,系統(tǒng)還沒有對這個請求真正處理,但是我們可以在這個請求傳遞到處理中心(HttpHandler)之前附加一些其它信息,或者截獲的這個請求并作一些額外的工作,也或者終止請求等。在HttpHandler處理完請求之后,我們可以再在相應(yīng)的HttpModule中把請求處理的結(jié)果進(jìn)行再次加工返回客戶端。

        HttpModule

        HTTP模塊是實(shí)現(xiàn)了System.Web.IhttpModule接口的類。

        IHttpModule接口的聲明:

        public interface IHttpModule

        {

        void Init (HttpApplication context);

        void Dispose ();

        }

        Init 方法:系統(tǒng)初始化的時候自動調(diào)用,這個方法允許HTTP模塊向HttpApplication 對象中的事件注冊自己的事件處理程序。

        Dispose方法: 這個方法給予HTTP模塊在對象被垃圾收集之前執(zhí)行清理的機(jī)會。此方法一般無需編寫代碼。

        HTTP模塊可以向System.Web.HttpApplication對象注冊下面一系列事件:

        AcquireRequestState 當(dāng)ASP.NET運(yùn)行時準(zhǔn)備好接收當(dāng)前HTTP請求的對話狀態(tài)的時候引發(fā)這個事件。

        AuthenticateRequest 當(dāng)ASP.NET 運(yùn)行時準(zhǔn)備驗(yàn)證用戶身份的時候引發(fā)這個事件。

        AuthorizeRequest 當(dāng)ASP.NET運(yùn)行時準(zhǔn)備授權(quán)用戶訪問資源的時候引發(fā)這個事件。

        BeginRequest 當(dāng)ASP.NET運(yùn)行時接收到新的HTTP請求的時候引發(fā)這個事件。

        Disposed 當(dāng)ASP.NET完成HTTP請求的處理過程時引發(fā)這個事件。

        EndRequest 把響應(yīng)內(nèi)容發(fā)送到客戶端之前引發(fā)這個事件。

        Error 在處理HTTP請求的過程中出現(xiàn)未處理異常的時候引發(fā)這個事件。

        PostRequestHandlerExecute 在HTTP處理程序結(jié)束執(zhí)行的時候引發(fā)這個事件。

        PreRequestHandlerExecute 在ASP.NET開始執(zhí)行HTTP請求的處理程序之前引發(fā)這個事件。在這個事件之后,ASP.NET 把該請求轉(zhuǎn)發(fā)給適當(dāng)?shù)腍TTP處理程序。

        PreSendRequestContent 在ASP.NET把響應(yīng)內(nèi)容發(fā)送到客戶端之前引發(fā)這個事件。這個事件允許我們在內(nèi)容到達(dá)客戶端之前改變響應(yīng)內(nèi)容。我們可以使用這個事件給頁面輸出添加用于所有頁面的內(nèi)容。例如通用菜單、頭信息或腳信息。

        PreSendRequestHeaders 在ASP.NET把HTTP響應(yīng)頭信息發(fā)送給客戶端之前引發(fā)這個事件。在頭信息到達(dá)客戶端之前,這個事件允許我們改變它的內(nèi)容。我們可以使用這個事件在頭信息中添加cookie和自定義數(shù)據(jù)。

        ReleaseRequestState 當(dāng)ASP.NET結(jié)束所搜有的請求處理程序執(zhí)行的時候引發(fā)這個事件。

        ResolveRequestCache 我們引發(fā)這個事件來決定是否可以使用從輸出緩沖返回的內(nèi)容來結(jié)束請求。這依賴于Web應(yīng)用程序的輸出緩沖時怎樣設(shè)置的。

        UpdateRequestCache 當(dāng)ASP.NET完成了當(dāng)前的HTTP請求的處理,并且輸出內(nèi)容已經(jīng)準(zhǔn)備好添加給輸出緩沖的時候,引發(fā)這個事件。這依賴于Web應(yīng)用程序的輸出緩沖是如何設(shè)置的。

        BeginRequest和PreRequestHandlerExecute之間的事件是在服務(wù)器執(zhí)行HttpHandler處理之前觸發(fā)。

        PostRequestHandlerExecute和PreSendRequestContent之間的事件是在服務(wù)器執(zhí)行Handler處理之后觸發(fā)。

        下面我們看一下如何使用HttpModule來實(shí)現(xiàn)我們?nèi)粘5膽?yīng)用:

        HttpModule通過在某些事件中注冊,把自己插入ASP.NET請求處理管道。當(dāng)這些事件發(fā)生的時候,ASP.NET調(diào)用對相應(yīng)的HTTP模塊,這樣該模塊就能處理請求了。

        1、向每個頁面動態(tài)添加一些備注或說明性的文字:

        有的網(wǎng)站每一個頁面都會彈出一個廣告或在每個頁面都以注釋形式(<!-- -->)加入網(wǎng)站的版權(quán)信息。如果在每個頁面教編寫這樣的JS代碼的話,對于大一點(diǎn)的網(wǎng)站,這種JS代碼的編寫與維護(hù)可是一個很繁瑣枯燥的工作。

        有了HttpModule我們就可以很簡單地解決這個問題了。HttpModule是客戶端發(fā)出請求到客戶端接收到服務(wù)器響應(yīng)之間的一段必經(jīng)之路。我們完全可以在服務(wù)器處理完請求之后,并在向客戶端發(fā)送響應(yīng)文本之前這段時機(jī),把這段注釋文字添加到頁面文本之后。這樣,每一個頁面請求都會被附加上這段注釋文字。

        這段代碼究竟該在哪個事件里實(shí)現(xiàn)呢? PostRequestHandlerExecute和PreSendRequestContent之間的任何一個事件都可以,但我比較喜歡在EndRequest事件里編寫代碼。

        第一步:創(chuàng)建一個類庫ClassLibrary831。

        第二步:編寫一個類實(shí)現(xiàn)IHttpModule接口

        class TestModule:IHttpModule

        {

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

        }

        }

        第三步:在Init事件中注冊EndRequest事件,并實(shí)現(xiàn)事件處理方法

        class TestModule:IHttpModule

        {

        public void Dispose(){}

        public void Init(HttpApplication context)

        {

        context.EndRequest += new EventHandler(context_EndRequest);

        }

        void context_EndRequest(object sender, EventArgs e)

        {

        HttpApplication ha = (HttpApplication)sender;

        ha.Response.Write("<!--這是每個頁面都會動態(tài)生成的文字。--grayworm-->");

        }

        }

        第四步:在Web.Conofig中注冊一下這個HttpModule模塊

        <httpModules>

        <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

        </httpModules>

        name:模塊名稱,一般是類名

        type:有兩部分組成,前半部分是命名空間和類名組成的全名,后半部分是程序集名稱,如果類是直接放在App_Code文件夾中,那程序名稱是App_Code。

        這樣在Web站點(diǎn)是添加該類庫的引用后,運(yùn)行每個頁面,會發(fā)現(xiàn)其源文件中都會加入“<!--這是每個頁面都會動態(tài)生成的文字。--grayworm-->”這句話。同樣的方法你也可以在其中加入JS代碼。
      2、身份檢查

        大家在作登錄時,登錄成功后,一般要把用戶名放在Session中保存,在其它每一個頁面的Page_Load事件中都檢查Session中是否存在用戶名,如果不存在就說明用戶未登錄,就不讓其訪問其中的內(nèi)容。

        在比較大的程序中,這種做法實(shí)在是太笨拙,因?yàn)槟銕缀跻诿恳粋€頁面中都加入檢測Session的代碼,導(dǎo)致難以開發(fā)和維護(hù)。下面我們看看如何使用HttpModule來減少我們的工作量

        由于在這里我們要用到Session中的內(nèi)容,我們只能在AcquireRequestState和PreRequestHandlerExecute事件中編寫代碼,因?yàn)樵贖ttpModule中只有這兩事件中可以訪問Session。這里我們選擇PreRequestHandlerExecute事件編寫代碼。

        第一步:創(chuàng)建一個類庫ClassLibrary831。

        第二步:編寫一個類實(shí)現(xiàn)IHttpModule接口

        class TestModule:IHttpModule

        {

        public void Dispose()

        {

        }

        public void Init(HttpApplication context)

        {

        }

        }

        第三步:在Init事件中注冊PreRequestHandlerExecute事件,并實(shí)現(xiàn)事件處理方法

        class AuthenticModule:IHttpModule

        {

        public void Dispose(){}

        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.ToString();

        int n = path.ToLower().IndexOf("Login.aspx");

        if (n == -1) //是否是登錄頁面,不是登錄頁面的話則進(jìn)入{}

        {

        if (ha.Context.Session["user"] == null) //是否Session中有用戶名,若是空的話,轉(zhuǎn)向登錄頁。

        {

        ha.Context.Response.Redirect("Login.aspx?source=" + path);

        }

        }

        }

        }

        第四步:在Login.aspx頁面的“登錄”按鈕中加入下面代碼

        protected void Button1_Click(object sender, EventArgs e)

        {

        if(true)    //判斷用戶名密碼是否正確

        {

        if (Request.QueryString["source"] != null)

        {

        string s = Request.QueryString["source"].ToLower().ToString();   //取出從哪個頁面轉(zhuǎn)來的

        Session["user"] = txtUID.Text;

        Response.Redirect(s); //轉(zhuǎn)到用戶想去的頁面

        }

        else

        {

        Response.Redirect("main.aspx");    //默認(rèn)轉(zhuǎn)向main.aspx

        }

        }

        }

        第五步:在Web.Conofig中注冊一下這個HttpModule模塊

        <httpModules>

        <add name="TestModule" type="ClassLibrary831.TestModule,ClassLibrary831"></add>

        </httpModules>
       3、多模塊的操作

        如果定義了多個HttpModule,在web.config文件中引入自定義HttpModule的順序就決定了多個自定義HttpModule在處理一個HTTP請求的接管順序。

        HttpHandler

        HttpHandler是HTTP請求的處理中心,真正地對客戶端請求的服務(wù)器頁面做出編譯和執(zhí)行,并將處理過后的信息附加在HTTP請求信息流中再次返回到HttpModule中。

        HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對系統(tǒng)的HttpHandler的關(guān)系將是“覆蓋”關(guān)系。

        IHttpHandler接口聲明

        public interface IHttpHandler

        {

        bool IsReusable { get; }

        public void ProcessRequest(HttpContext context); //請求處理函數(shù)

        }

        示例:把硬盤上的圖片以流的方式寫在頁面上

        class TestHandler : IHttpHandler

        {

        public void ProcessRequest(HttpContext context)

        {

        FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);

        byte[] b = new byte[fs.Length];

        fs.Read(b, 0, (int)fs.Length);

        fs.Close();

        context.Response.OutputStream.Write(b, 0, b.Length);

        }

        public bool IsReusable

        {

        get

        {

        return true;

        }

        }

        }

        Web.Config配置文件

        <httpHandlers>

        <add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>

        </httpHandlers>

        Verb屬性:指定了處理程序支持的HTTP動作。*-支持所有的HTTP動作;“GET”-支持Get操作;“POST”-支持Post操作;“GET, POST”-支持兩種操作。

        Path屬性:指定了需要調(diào)用處理程序的路徑和文件名(可以包含通配符)。“*”、“*.aspx”、“showImage.aspx”、“test1.aspx,test2.aspx”

        Type屬性:用名字空間、類名稱和程序集名稱的組合形式指定處理程序或處理程序工廠的實(shí)際類型。ASP.NET運(yùn)行時首先搜索bin目錄中的DLL,接著在GAC中搜索。

        這樣程序運(yùn)行的效果是該網(wǎng)站的任何一個頁面都會顯示worm.jpg圖片。如何只讓一個頁面(default21.aspx)執(zhí)行HttpHandler 中的ProcessRequest方法呢?最簡單的辦法是在Web.Config文件中把path配置信息設(shè)為default21.aspx。

        根據(jù)這個例子大家可以考慮一下如何編寫“驗(yàn)證碼”了。

        IHttpHandler工廠

        IHttpHandlerFactory的作用是對IHttpHandler進(jìn)行管理。工廠的作用請見http://hi.baidu.com/grayworm/blog/item/4a832160f8c9de46eaf8f8c1.html"

        IHttpHandlerFactory接口的聲明:

        public interface IHttpHandlerFactory

        {

        IHttpHandler GetHandler (HttpContext context,string requestType,string url,string pathTranslated);

        void ReleaseHandler (IHttpHandler handler);

        }

        GetHandler返回實(shí)現(xiàn)IHttpHandler接口的類的實(shí)例,ReleaseHandler使工廠可以重用現(xiàn)有的處理程序?qū)嵗?/p>

        示例:兩個用IHttpHandlerFactory來實(shí)現(xiàn)對不同HttpHandler的調(diào)用。

        有兩個HttpHandler:將圖片顯示在頁面上的HttpHandler和生成驗(yàn)證碼的Handler

        //將圖片顯示在頁面上的Handler

        class TestHandler : IHttpHandler

        {

        public void ProcessRequest(HttpContext context)

        {

        FileStream fs = new FileStream(context.Server.MapPath("worm.jpg"), FileMode.Open);

        byte[] b = new byte[fs.Length];

        fs.Read(b, 0, (int)fs.Length);

        fs.Close();

        context.Response.OutputStream.Write(b, 0, b.Length);

        }

        public bool IsReusable

        {

        get

        {

        return true;

        }

        }

        }
      //生成驗(yàn)證碼的Handler

        class CodeHandler:IHttpHandler

        {

        public bool IsReusable

        {

        get

        {

        return true;

        }

        }

        public void ProcessRequest(HttpContext context)

        {

        Image b = new Bitmap(50,20);

        Graphics g = Graphics.FromImage(b);

        SolidBrush sb = new SolidBrush(Color.White);

        Font f = new Font("宋體", 12);

        string str = "";

        Random r = new Random();

        for (int i = 0; i < 4; i++)

        {

        str += r.Next(10);

        }

        g.DrawString(str,f,sb,0,0);

        b.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);

        }

        }

        IHttpHandler工廠

        class TestHandlerFactory : IHttpHandlerFactory

        {

        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)

        {

        string fname = url.Substring(url.IndexOf('/') + 1);

        while (fname.IndexOf('/') != -1)

        fname = fname.Substring(fname.IndexOf('/') + 1);

        string cname = fname.Substring(0, fname.IndexOf('.'));

        string className ="";

        className = "ClassLibrary831.CodeHandler";

        object h = null;

        try

        {

        //h = new TestHandler();

        h = Activator.CreateInstance(Type.GetType(className));

        }

        catch (Exception e)

        {

        throw new HttpException("工廠不能為類型" + cname + "創(chuàng)建實(shí)例。", e);

        }

        return (IHttpHandler)h;

        }

        public void ReleaseHandler(IHttpHandler handler)

        {

        }

        }(車延祿)

        配置文件

        <httpHandlers>

        <add verb="*" path="default21.aspx,default22.aspx" type="ClassLibrary831.TestHandlerFactory,ClassLibrary831"></add>

        </httpHandlers>

        這樣TestHandlerFactory就會根據(jù)請求的不同頁面執(zhí)行不同的HttpHandler處理程序了。

        HttpHandler使用會話

        如果要在處理程序中使用Session,那必須把該HttpHandler實(shí)現(xiàn)IRequiresSessionState接口,,IRequiresSessionState接口是個空接口,它沒有抽象方法,只是一個標(biāo)記。此處就不作例子驗(yàn)證了

        寧可去碰壁,也不在家面壁;緣于自然,順其自然。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多