首页

源码搜藏网

首页 > 开发教程 >

细说 HttpHandler 的映射过程

创建时间:2014-03-11 11:12  

在ASP.NET编程模型中,一个来自客户端的请求要经过一个称为管线的处理过程。 在整个处理请求中,相对于其它对象来说,HttpHandler的处理算得上是整个过程的核心部分。 由于HttpHandler的重要地位,我前面已经有二篇博客对它过一些使用上的介绍。 【用Asp.net写自己的服务框架】 中谈到了它的一般使用方法。 【细说ASP.NET的各种异步操作】 又详细地介绍了异步HttpHandler的使用方式。

今天的博客将着重介绍HttpHandler的配置,创建以及重用过程,还将涉及HttpHandlerFactory的内容。

回顾HttpHandler

HttpHandler其实是一类统称:泛指实现了IHttpHandler接口的一些类型,这些类型有一个共同的功能,那就是可以用来处理HTTP请求。 IHttpHandler的接口定义如下:

// 定义 ASP.NET 为使用自定义 HTTP 处理程序同步处理 HTTP Web 请求而实现的协定。
public interface IHttpHandler
{
    // 获取一个值,该值指示其他请求是否可以使用 System.Web.IHttpHandler 实例。
    //
    // 返回结果:
    //     如果 System.Web.IHttpHandler 实例可再次使用,则为 true;否则为 false。
    bool IsReusable { get; }

    // 通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。
    void ProcessRequest(HttpContext context);
}

有关HttpHandler的各类用法,可参考我的博客【用Asp.net写自己的服务框架】, 本文将不再重复说明了。它还有一个异步版本:

// 摘要:
//     定义 HTTP 异步处理程序对象必须实现的协定。
public interface IHttpAsyncHandler : IHttpHandler
{
    // 摘要:
    //     启动对 HTTP 处理程序的异步调用。
    //
    // 参数:
    //   context:
    //     一个 System.Web.HttpContext 对象,该对象提供对用于向 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session
    //     和 Server)的引用。
    //
    //   extraData:
    //     处理该请求所需的所有额外数据。
    //
    //   cb:
    //     异步方法调用完成时要调用的 System.AsyncCallback。如果 cb 为 null,则不调用委托。
    //
    // 返回结果:
    //     包含有关进程状态信息的 System.IAsyncResult。
    IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData);
    //
    // 摘要:
    //     进程结束时提供异步处理 End 方法。
    //
    // 参数:
    //   result:
    //     包含有关进程状态信息的 System.IAsyncResult。
    void EndProcessRequest(IAsyncResult result);
}

IHttpAsyncHandler接口的二个方法该如何使用,可参考我的博客【细说ASP.NET的各种异步操作】, 本文也将不再重复讲解。

如果我们创建了一个自定义的HttpHandler,那么为了能让它处理某些HTTP请求,我们还需将它注册到web.config中,就像下面这样:


<httpHandlers>
    <add path="*.fish" verb="*" validate="true" type="MySimpleServiceFramework.AjaxServiceHandler"/>
</httpHandlers>

虽然我以前的博客中也曾多次涉及到HttpHandler,但感觉还是没有把它完整地说清楚,今天的博客将继续以前的话题,因为我认为HttpHandler实在是太重要了。

HttpHandler的映射过程

在博客【用Asp.net写自己的服务框架】中, 我从MSDN中摘选了一些ASP.NET管线事件,在这些事件中,第10个事件【根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理】 就是本文要介绍的重点事件。这个事件也是HttpHandler创建的地方。

由于IIS6,7在管线事件触发机制上的有一定的差别,本文将以ASP.NET 2.0以及IIS6的运行方式来介绍这个过程, IIS7的集成模式下只是触发机制不同,但事件的绝大部分是一样的。 管线事件由HttpApplication控制,由MapHandlerExecutionStep负责封装这个事件的执行过程:

Execute()最终调用了MapHttpHandler()方法,这个映射过程是由HttpApplication实现的。
MapHttpHandler方法的实现如下:注意代码中我加入的注释。

今天的代码将着重分析这段代码,以揭示HttpHandler的映射过程。

在这段代码中,有3个主要的调用过程:
1. this.GetHandlerMapping(context, requestType, path, useAppConfig)
2. this.GetFactory(mapping)
3. factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated)
后面将着重分析这三个调用。

HttpContext.RemapHandler()

在MapHttpHandler()方法的开始处,有这么一段代码,不知您注意没有?


IHttpHandler handler = (context.ServerExecuteDepth == 0)  context.RemapHandlerInstance : null;

if( handler != null )
    return handler;

这段代码是什么意思呢?
为了能让您较为简单地理解这段代码的意义,请看我准备的一个示例:
我创建了一个TestRemapHandler.ashx文件:

至于这个文件在运行时能输出什么,我想我就不用截图了。
接下来,我再创建一个Global.asax文件,并写了一个事件处理方法:

上一篇:细说 ASP.NET控制HTTP缓存
下一篇:写自己的ASP.NET MVC框架(上)

相关内容

热门推荐