概述
HttpHandler 是一个 HTTP 请求的真正处理中心,也正是在这个 HttpHandler 容器中, ASP.NET Framework 才真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在 HTTP 请求信息流中再次返回到 HttpModule 中。
 
IHttpHandler 是什么
IHttpHandler 定义了如果要实现一个 HTTP 请求的处理所必需实现的一些系统约定。 HttpHandler HttpModule 不同,一旦定义了自己的 HttpHandler 类,那么它对系统的 HttpHandler 的关系将是“覆盖”关系。
 
IHttpHandler 如何处理 HTTP 请求
当一个 HTTP 请求经同 HttpModule 容器传递到 HttpHandler 容器中时, ASP.NET Framework 会调用 HttpHandler Proce***equest 成员方法来对这个 HTTP 请求进行真正的处理。以一个 ASPX 页面为例,正是在这里一个 ASPX 页面才被系统处理解析,并将处理完成的结果继续经由 HttpModule 传递下去,直至到达客户端。
对于 ASPX 页面, ASP.NET Framework 在默认情况下是交给 System.Web.UI.PageHandlerFactory 这个 HttpHandlerFactory 来处理的。所谓一个 HttpHandlerFactory ,所谓一个 HttpHandlerFactory ,是指当一个 HTTP 请求到达这个 HttpHandler Factory 时, HttpHandlerFactory 会提供出一个 HttpHandler 容器,交由这个 HttpHandler 容器来处理这个 HTTP 请求。
一个 HTTP 请求都是最终交给一个 HttpHandler 容器中的 Proce***equest 方法来处理的。

1 Proce***equest 方法
 

一个简单的
HttpHandler 容器
通过实现 IHttpHandler 接口可以创建自定义 HTTP 处理程序,该接口只包含两个方法。通过调用 IsReusable IHttpHandlerFactory 可以查询处理程序以确定是否可以使用同一实例为多个请求提供服务。 Proce***equest 方法将 HttpContext 实例用作参数,这使它能够访问 Request Response 内部对象。在一个 HttpHandler 容器中如果需要访问 Session ,必须实现 IRequiresSessionState 接口,这只是一个标记接口,没有任何方法。

using System;

using System.Collections.Generic;

using System.Text;

using System.Web;

using System.Web.SessionState;

    

namespace MyHandler

{

         ///

         /// 目的:实现一个简单的自定义HttpHandler容器

         /// 作者:文野

         /// 联系:[email protected]

         ///


         public class MyFirstHandler : IHttpHandler,IRequiresSessionState

        {

IHttpHandler 成员 #region IHttpHandler 成员

    

                 public bool IsReusable

                {

                        get { return true; }

                }

    

                 public void Proce***equest(HttpContext context)

                {

                        context.Response.Write( "

Hello HttpHandler

"
);

                        context.Session[ "Test"] = "测试HttpHandler容器中调用Session";

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

                }

    

                #endregion

        }

}

在Web.config中加入如下配置:



         "*" path= "*" type= "MyHandler.MyFirstHandler, MyHandler"/>



IHttpHandler 工厂
ASP.NET Framework 实际不直接将相关的页面资源 HTTP 请求定位到一个其内部默认的 IHttpHandler 容器之上,而定位到了其内部默认的 IHttpHandler 工厂上。 IHttpHandler 工厂的作用是对 IHttpHandler 容器进行调度和管理。
IHttpHandlerFactory 接口包含两个方法。 GetHandler 返回实现 IHttpHandler 接口的类的实例, ReleaseHandler 使工厂可以重用现有的处理程序实例。
 
示例 2
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
 
namespace MyHandler
{
    public class MyHandlerFactory : IHttpHandlerFactory
    {
        #region 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 = "MyHandler." + cname;
 
            object h = null;
 
            try
            {
                // 采用动态反射机制创建相应的IHttpHandler实现类。
                h = Activator.CreateInstance(Type.GetType(className));
            }
            catch (Exception e)
            {
                throw new HttpException(" 工厂不能为类型" +cname+" 创建实例。" ,e);
            }
 
            return (IHttpHandler)h;
        }
 
        public void ReleaseHandler(IHttpHandler handler)
        {
           
        }
 
        #endregion
    }
 
    public class Handler1 : IHttpHandler
    {
        #region IHttpHandler 成员
 
        public bool IsReusable
        {
            get { return true; }
        }
 
        public void Proce***equest(HttpContext context)
        {
            context.Response.Write("

来自Handler1的信息。

"
);
        }
 
        #endregion
    }
 
    public class Handler2 : IHttpHandler
    {
        #region IHttpHandler 成员
 
        public bool IsReusable
        {
            get { return true; }
        }
 
        public void Proce***equest(HttpContext context)
        {
            context.Response.Write("

来自Handler2的信息。

"
);
        }
 
        #endregion
    }
}