HttpModule、HttpHandler-初识与区别

作者: 来源: 日期:2009-2-23

HttpModule 中不能使用 Session 相关的,比如 httpContext.User 总为 null。

HttpHandler 中可以使用 Session 相关的,比如 httpContext.User 是可以取到值的。

以上ITPOW编辑注。

通俗点讲

HttpModule 倾向于拦截访问,比如你明明访问的是 1.jpg,我给你拦截了。

HttpHandler 倾向于映射访问,比如它指定当访问 a.do 交由某某类处理,当访问 b.do 交由另外一个类处理。

具体见了本连载的两个示例就清楚了。

以上为ITPOW编辑注,以下为网上转载。

在以前的 ASP 时候,当请求一个 *.asp 页面文件的时候,这个 HTTP 请求首先会被一个名为 inetinfo.exe 进程所截获,这个进程实际上就是 www 服务。截获之后它会将这个请求转交给 asp.dll 进程,这个进程就会解释这个 asp 页面,然后将解释后的数据流返回给客户端浏览器。其实 asp.dll 是一个依附在 IIS 的 ISAPI 文件,它负责了对诸如 ASP 文件,ASA 等文件的解释执行。

ASP.NET 的 HTTP 请求处理方法

当客户端向 web 服务器请求一个 *.aspx 的页面文件时,同 asp 类似,这个 http 请求也会被 inetinfo.exe 进程截获(www 服务),它判断文件后缀之后,把这个请求转交给 ASPNET_ISAPI.DLL 而 ASPNET_ISAPI.DLL 则会通过一个 Http PipeLine 的管道,将这个 http 请求发送给 ASPNET_WP.EXE 进程,当这个 HTTP 请求进入 ASPNET_WP.EXE 进程之后,asp.net framework 就会通过 HttpRuntime 来处理这个 Http 请求,处理完毕后将结果返回给客户端。

当一个 http 请求被送入到 HttpRuntime 之后,这个 Http 请求会继续被送入到一个被称之为 HttpApplication Factory 的一个容器当中,而这个容器会给出一个 HttpApplication 实例来处理传递进来的http请求,而后这个 Http 请求会依次进入到如下几个容器中:

HttpModule --> HttpHandler Factory --> HttpHandler

当系统内部的 HttpHandler 的 ProcessRequest 方法处理完毕之后,整个 Http Request 就被处理完成了,客户端也就得到相应的东东了。

完整的 http 请求在 asp.net framework 中的处理流程:

HttpRequest-->inetinfo.exe->ASPNET_ISAPI.DLL-->Http Pipeline-->ASPNET_WP.EXE-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

如果想在中途截获一个 httpRequest 并做些自己的处理,就应该在 HttpRuntime 运行时内部来做到这一点,确切的说时在 HttpModule 这个容器中做到这个的。

系统本身的 HttpModule 实现一个 IHttpModule 的接口,当然我们自己的类也能够实现 IHttpModule 接口,这就可以替代系统的 HttpModule 对象了。
ASP.NET 系统中默认的 HttpModule:

  • DefaultAuthenticationModule 确保上下文中存在 Authentication 对象。无法继承此类。
  • FileAuthorizationModule 验证远程用户是否具有访问所请求文件的 NT 权限。无法继承此类。
  • FormsAuthenticationModule 启用 ASP.NET 应用程序以使用 Forms 身份验证。无法继承此类。
  • PassportAuthenticationModule 提供环绕 PassportAuthentication 服务的包装。无法继承此类。
  • SessionStateModule 为应用程序提供会话状态服务。
  • UrlAuthorizationModule 提供基于 URL 的授权服务以允许或拒绝对指定资源的访问。无法继承此类。
  • WindowsAuthenticationModule 启用 ASP.NET 应用程序以使用 Windows/IIS 身份验证。无法继承此类。

这些系统默认的 HttpModule 是在文件 machine.config 中配置的,和我们开发时使用到的 web.config 的关系是:是在 ASP.NET FRAMEWORK 启动处理一个 Http Request 的时候,它会依次加载 machine.config 和请求页面所在目录的 web.config 文件,如果在 machine 中配置了一个自己的 HttpModule,你仍然可以在所在页面的 web.config 文件中 remove 掉这个映射关系。

public class HelloWorldModule : IHttpModule
{
    public HelloWorldModule()
    {
    }
   
    public String ModuleName
    {
        get { return "HelloWorldModule"; }
    }
   
    // In the Init function, register for HttpApplication
    // events by adding your handlers.
    public void Init(HttpApplication application)
    {
        application.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest +=
            (new EventHandler(this.Application_EndRequest));
    }
   
    private void Application_BeginRequest(Object source,
         EventArgs e)
    {
        // Create HttpApplication and HttpContext objects to access
        // request and response properties.
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<h1><font color=red> HelloWorldModule: Beginning of Request</font></h1><hr>");
    }
   
    private void Application_EndRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>");
    }
   
    public void Dispose()
    {
    }
}

 

<system.web>
  <httpModules>
    <add name="HelloWorldModule" type="HelloWorldModule"/>
  </httpModules>
</system.web>

深入 HttpModule

一个 Http 请求在被 ASP.NET Framework 捕获之后会依次交给 HttpModule 以及 HttpHandler 来处理。hm 与 hh 之间不是完全独立的,实际上,http 请求在 hm 传递的过程中会在某个事件内将控制权转交给 hh 的,而真正的处理在 HttpHandler 中执行完成后,HttpHandler 会再次将控制权交还给 HttpModule。

上面的代码中的 HttpModule的Init() 中的参数是 HttpApplication 类型,它具有许多事件,包括 BeginRequest、EndRequest、AuthentiacteRequest 等等。

IHttpHandler

它是 asp.net Framework 提供的一个接口,定义了如果要实现一个 Http 请求的处理所需要必须实现的一些系统约定。也就是说,如果你想要自行处理某些类型的 HTTP 请求信息流的话,你需要实现这些系统约定才能做到。譬如一个 *.aspx 文件,用来处理此类型的 Http 请求,ASP.NET FRAMEWORK 将会交给一个名为 System.Web.UI.PageHandlerFactory 的 HttpHandler 类来处理。

HH 和 HM 一样,系统会在最初始由 ASP.NET FRAMEWORK 首先加载 machine.config 中的 HttpHandler,而后会加载 Web 应用程序所在目录的 web.config 中的用户自定义的 HttpHandler 类。但是系统与我们自定义的 HH 之间的关系是"覆盖"的,也就是说如果我们自定义了一个针对 *.aspx 的 HttpHandler 类的话,那么系统会将对此 http 请求的处理权完全交给我们自己定义的这个 HttpHandler 类来处理,而我们自己的 HttpHandler 类则需要自己完全解析这个 Http 请求,并作出处理。

IHttpHandler 接口中最重要的方法 ProcessRequest,这个方法就是 HttpHandler 用来处理一个 Http 请求,当一个 Http 请求经过由 HttpModule 容器传递到 HttpHandler 容器中的时候,framework 会调用HttpHandler 的 ProcessRequest 方法来做对这个 Http 请求做真正的处理。

Framework 实际上并不是直接把相关页面的 HTTP 请求定位到一个内部默认的IHttpHandler 容器之上的,而是定位到了其内部默认的 IHttpHandler Factory 上了。IHttpHandler Factory 的作用就是对很多系统已经实现了的 IHttpHandler 容器进行调度和管理的,这样做的优点是大大增强了系统的负荷性,提升了效率。

相关文章