天天看點

深入了解asp.net裡的IHttpHandler

深入了解asp.net裡的IHttpHandler

忍不住了,繼續貼。

1 、概述

深入了解asp.net裡的IHttpHandler

說 明:HttpHandler是一個HTTP請求的真正進行中心。在HttpHandler容器中,ASP.NET Framework才調用HttpHandler的ProcessRequest成員方法來對這個HTTP請求進行真正的處理,真正地對用戶端請求的服務 器頁面做出編譯和執行,并将處理過後的資訊附加在HTTP請求資訊流中再次傳回到HttpModule中。

2、舉例

以一個aspx頁面為 例,正是在HttpHandler這裡,一個aspx頁面才被系統處了解析,并将處理完成的結果繼續經由HttpModule傳遞下去,直至到達用戶端。 當然,對于aspx頁面,ASP.NET Framework在預設情況下是交給System.Web.UI.PageHandlerFactory這個HttpHandlerFactory 來處理的。當一個HTTP請求到達這個HttpHandlerFactory時,HttpHandlerFactory會提供出一個HttpHandler容器,交由這個HttpHandler容器來處理這個HTTP請求。 一個HTTP請求都是最終交給一個HttpHandler容器中的ProcessRequest方法來處理的。

3、HttpHandler

(1)實作HttpHandler,必須繼承自IHttpHandler接口。下面是這個接口的定義:

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

using  System;

namespace  System.Web

{

     //  Summary:

     //      Defines the contract that ASP.NET implements to synchronously process HTTP

     //      Web requests using custom HTTP handlers.

     public   interface  IHttpHandler

    {

         //  Summary:

         //      Gets a value indicating whether another request can use the System.Web.IHttpHandler

         //      instance.

         //

         //  Returns:

         //      true if the System.Web.IHttpHandler instance is reusable; otherwise, false.

         //   其他Request是否可以使用IHttpHandler

         bool  IsReusable {  get ; }

         //  Summary:

         //      Enables processing of HTTP Web requests by a custom HttpHandler that implements

         //      the System.Web.IHttpHandler interface.

         //

         //  Parameters:

         //    context:

         //      An System.Web.HttpContext object that provides references to the intrinsic

         //      server objects (for example, Request, Response, Session, and Server) used

         //      to service HTTP requests.

         //   處理HttpRequest

         void  ProcessRequest(HttpContext context);

    }

}

(2)自定義HttpHandler

a、代碼

建立一個網站,default.aspx頁面:

default.aspx.cs:

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

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;

public   partial   class  _Default : System.Web.UI.Page

{

     protected   void  Page_Load( object  sender, EventArgs e)

    {

        Response.Write( " <br/>來自Default.aspx頁面<br/> " );

    }

}

新添一個類庫MyHandler,添加一個類如下:

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

using  System;

using  System.Collections.Generic;

using  System.Text;

using  System.Web;

using  System.Web.SessionState;

namespace  MyHandler

{

     ///   <summary>

     ///  如果要在HttpHandler容器中使用Session,必須要實作IRequiresSessionState接口

     ///   </summary>

     public   class  MyTestHandler : IHttpHandler, IRequiresSessionState

    {

         public   bool  IsReusable

        {

             get  {  return   true ; }

        }

         public   void  ProcessRequest(HttpContext context)

        {

            context.Response.Write( " <h3><b>This is a HttpHandler Test</b></h3> " );

            context.Session[ " Test " ]  =   " <h3><span style=/ " color:blue;/ " >在HttpHandler容器中調用Session</span></h3> " ;

            context.Response.Write(context.Session[ " Test " ]);

        }

    }

}

要在HttpHandler使用Session,我在舊文aspx,ascx和ashx使用小結 裡已經提及。

b、配置檔案

在web.config檔案的system.web節點下,添加:

      <httpHandlers>        

        <add verb="*" path="*" type="MyHandler.MyTestHandler, MyHandler"/>

      </httpHandlers>

c、注意

<1>、.NET為asp.net提供了很多系統預設HttpHandler類,用來适應不同類型的HttpRequest。比如aspx,在machine.config中是這樣定義的:   

        <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>

這就說明遇到aspx的Request請求,asp.net會将其交給System.Web.UI.PageHandlerFactory的HttpHandler類來處理。

<2>、如果自己定義了新的HttpHandler,而且在web.config中指定,則系統隻會使用這個新的HttpHandler,而不再使用原先預設的或者指定的.

<3>、直接拷貝類庫的bin目錄下的檔案到網站bin下.

4、HttpHandlerFactory

ASP.NET Framework實際不直接将相關的頁面資源HTTP請求定位到一個其内部預設的IHttpHandler容器之上,而定位到了其内部預設的 IHttpHandler工廠上。IHttpHandler工廠的作用是對IHttpHandler容器進行排程和管理,這樣做的優點是大大增強了系統的 負荷性,提升了效率。

(1)IHttpHandlerFactory接口

 IHttpHandlerFactory接口包含兩個方法:GetHandler方法傳回實作IHttpHandler接口的類的執行個體,ReleaseHandler方法使工廠可以重用現有的處理程式執行個體。

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

using  System;

using  System.Web;

namespace  System.Web.UI

{

     //  Summary:

     //      Creates instances of classes that inherit from the System.Web.UI.Page class

     //      and implement the System.Web.IHttpHandler interface. Instances are created

     //      dynamically to handle requests for ASP.NET files. The System.Web.UI.PageHandlerFactory

     //      class is the default handler factory implementation for ASP.NET pages.  

     public   class  PageHandlerFactory : System.Web.IHttpHandlerFactory2, IHttpHandlerFactory

    {

         //  Summary:

         //      Initializes a new instance of the System.Web.UI.PageHandlerFactory class.

         protected   internal  PageHandlerFactory();

         //  Summary:

         //      Returns an instance of the System.Web.IHttpHandler interface to process the

         //      requested resource.

         //

         //  Parameters:

         //    context:

         //      An instance of the System.Web.HttpContext class that provides references

         //      to intrinsic server objects (for example, Request, Response, Session, and

         //      Server) used to service HTTP requests.

         //

         //    requestType:

         //      The HTTP data transfer method (GET or POST) that the client uses.

         //

         //    virtualPath:

         //      The virtual path to the requested resource.

         //

         //    path:

         //      The System.Web.HttpRequest.PhysicalApplicationPath property to the requested

         //      resource.

         //

         //  Returns:

         //      A new System.Web.IHttpHandler that processes the request; otherwise, null.

         public   virtual  IHttpHandler GetHandler(HttpContext context,  string  requestType,  string  virtualPath,  string  path);

         //

         //  Summary:

         //      Enables a factory to reuse an existing instance of a handler.

         //

         //  Parameters:

         //    handler:

         //      The System.Web.IHttpHandler to reuse.

         public   virtual   void  ReleaseHandler(IHttpHandler handler);

    }

}

(2) 實作一個簡單的HttpHandler工廠

類庫新添一個檔案MyHandlerFactor.cs:

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

using  System;

using  System.Collections.Generic;

using  System.Text;

using  System.Web;

namespace  MyHandler

{

     public   class  MyHandlerFactory : IHttpHandlerFactory

    {

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

        {

             string  fileName  =  url.Substring(url.LastIndexOf( ' / ' )  +   1 );

             string  objName  =  fileName.Substring( 0 , fileName.IndexOf( ' . ' ));

             string  className  =   " MyHandler. "   +  objName;

             object  objHandler  =   null ;

             try

            {

                 //  采用動态反射機制建立相應的IHttpHandler實作類。

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

                context.Response.Write(className);

                 // context.Response.Redirect("default.aspx");

            }

             catch  (Exception e)

            {

                 throw   new  HttpException( " 工廠不能為類型 "   +  objName  +   " 建立執行個體。 " , e);

            }

             return  (IHttpHandler)objHandler;

        }

         public   void  ReleaseHandler(IHttpHandler handler)

        {

        }

    }

     public   class  Handler1 : IHttpHandler

    {

         public   bool  IsReusable

        {

             get  {  return   true ; }

        }

         public   void  ProcessRequest(HttpContext context)

        {

            context.Response.Write( " <br/>這是來自于MyHandlerFactory裡的處理.<br/> " );

            context.Response.Write( " <h3>來自Handler1的資訊.</h3> " );

        }

    }

     public   class  Handler2 : IHttpHandler

    {

         public   bool  IsReusable

        {

             get  {  return   true ; }

        }

         public   void  ProcessRequest(HttpContext context)

        {

            context.Response.Write( " <br/>這是來自于MyHandlerFactory裡的處理.<br/> " );

            context.Response.Write( " <h3>來自Handler2的資訊.</h3> " );

        }

    }

}

網站新添兩個檔案,Handler1.aspx和Handler2.aspx。它們的cs檔案:

深入了解asp.net裡的IHttpHandler
深入了解asp.net裡的IHttpHandler

Code

using  System;

using  System.Data;

using  System.Configuration;

using  System.Collections;

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;

public   partial   class  Handler1 : System.Web.UI.Page

{

     protected   void  Page_Load( object  sender, EventArgs e)

    {

           Response.Write( " 這是來自于MyHandler頁面直接輸出... " );  // 這一句不起作用了,MyHandlerFactory已經對該頁面的HttpContext進行了處理

    }

}

接着重新修改配置檔案:

      <httpHandlers> 

           <add verb="*" path="Handler1.aspx" type="MyHandler.MyHandlerFactory, MyHandler"/>

           <add verb="*" path="Handler2.aspx" type="MyHandler.MyHandlerFactory, MyHandler"/>

      </httpHandlers>

到這裡,針對Handler1.aspx和Handler2.aspx兩個頁面的http請求我們就通過HttpHandler工廠處理好了。

5、HttpHandler和HttpModule的差別

主要有兩點:

 (1)先後次序.先IHttpModule,後IHttpHandler,IHttpHandler處理結束後再交給IHttpModule;

 (2)對請求的處理上:

        IHttpModule是屬于大小通吃類型,無論用戶端請求的是什麼檔案,都會調用到它;例如aspx,html,rar的請求;

        IHttpHandler則屬于挑食類型,隻有asp.net注冊過的檔案類型(例如aspx,ascx,asmx等等)才會輪到調用它。

繼續閱讀