天天看点

深入理解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等等)才会轮到调用它。

继续阅读