天天看点

Httphandle Httpmodule HttpHandler Factory 学习整理

ASP.NET Framework处理一个Http Request的流程:

    HttpRequest-->inetinfo.exe-->ASPNET_ISAPI.dll-->ASPNET_WP.exe-->HttpRuntime-->HttpApplication Factory-->HttpApplication-->HttpModule-->HttpHandler Factory-->HttpHandler-->HttpHandler.ProcessRequest()

在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。但我们可以使用HttpHandler Factory来选择使用哪个HttpHandler。

HttpModule

当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于HTTP请求来讲,HttpModule是一个HTTP请求的“必经之路”,所以可以在这个HTTP请求传递到真正的请求处理中心(HttpHandler)之前附加一些需要的信息在这个HTTP请求信息之上,或者针对截获的这个HTTP请求信息作一些额外的工作,或者在某些情况下干脆终止满足一些条件的HTTP请求,从而可以起到一个Filter过滤器的作用。

一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的HTTP请求处理工作。

而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到客户端为止。

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

Httphandle Httpmodule HttpHandler Factory 学习整理

    HTTP模块是实现了System.Web.IhttpModule接口的类。

    IHttpModule接口的声明:

public interface IHttpModule

        {

            void Init (HttpApplication context); //初始化,事件注册

            void Dispose ();

        }

Init 方法:系统初始化的时候自动调用,这个方法允许HTTP模块向HttpApplication 对象中的事件注册自己的事件处理程序。

Dispose方法: 这个方法给予HTTP模块在对象被垃圾收集之前执行清理的机会。此方法一般无需编写代码。

    HTTP模块可以向System.Web.HttpApplication对象注册下面一系列事件:

AcquireRequestState 当ASP.NET运行时准备好接收当前HTTP请求的对话状态的时候引发这个事件。

AuthenticateRequest 当ASP.NET 运行时准备验证用户身份的时候引发这个事件。

AuthorizeRequest 当ASP.NET运行时准备授权用户访问资源的时候引发这个事件。

BeginRequest 当ASP.NET运行时接收到新的HTTP请求的时候引发这个事件。

Disposed 当ASP.NET完成HTTP请求的处理过程时引发这个事件。

EndRequest 把响应内容发送到客户端之前引发这个事件。

Error 在处理HTTP请求的过程中出现未处理异常的时候引发这个事件。

PostRequestHandlerExecute 在HTTP处理程序结束执行的时候引发这个事件。

PreRequestHandlerExecute 在ASP.NET开始执行HTTP请求的处理程序之前引发这个事件。在这个事件之后,ASP.NET 把该请求转发给适当的HTTP处理程序。

PreSendRequestContent 在ASP.NET把响应内容发送到客户端之前引发这个事件。这个事件允许我们在内容到达客户端之前改变响应内容。我们可以使用这个事件给页面输出添加用于所有页面的内容。例如通用菜单、头信息或脚信息。

PreSendRequestHeaders 在ASP.NET把HTTP响应头信息发送给客户端之前引发这个事件。在头信息到达客户端之前,这个事件允许我们改变它的内容。我们可以使用这个事件在头信息中添加cookie和自定义数据。

ReleaseRequestState 当ASP.NET结束所搜有的请求处理程序执行的时候引发这个事件。

ResolveRequestCache 我们引发这个事件来决定是否可以使用从输出缓冲返回的内容来结束请求。这依赖于Web应用程序的输出缓冲时怎样设置的。

UpdateRequestCache 当ASP.NET完成了当前的HTTP请求的处理,并且输出内容已经准备好添加给输出缓冲的时候,引发这个事件。这依赖于Web应用程序的输出缓冲是如何设置的。

HttpHandler

    HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。

    HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系。

    IHttpHandler接口声明

public interface IHttpHandler

    {

        bool IsReusable { get; }

        public void ProcessRequest(HttpContext context); //请求处理函数

    }

Web.Config配置文件

<httpHandlers>

       <add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>

      </httpHandlers>

Verb属性:指定了处理程序支持的HTTP动作。*-支持所有的HTTP动作;“GET”-支持Get操作;“POST”-支持Post操作;“GET, POST”-支持两种操作。

Path属性:指定了需要调用处理程序的路径和文件名(可以包含通配符)。“*”、“*.aspx”、“showImage.aspx”、“test1.aspx,test2.aspx”

Type属性:用名字空间、类名称和程序集名称的组合形式指定处理程序或处理程序工厂的实际类型。ASP.NET运行时首先搜索bin目录中的DLL,接着在GAC中搜索。

IHttpHandler工厂

IHttpHandlerFactory的作用是对IHttpHandler进行管理。比如针对不同的两个页面需要使用两个不同的HttpHandler进行处理时,使用IHttpHandlerFactory管理。

IHttpHandlerFactory接口的声明:

public interface IHttpHandlerFactory

        {

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

            void ReleaseHandler (IHttpHandler handler);

        }

参数

context

类型: System.WebHttpContext

HttpContext 类的实例,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。

requestType

类型: SystemString

客户端使用的 HTTP 数据传输方法(GET 或 POST)。

virtualPath

类型: SystemString

所请求资源的虚拟路径。

path

类型: SystemString

所请求资源的 PhysicalApplicationPath 属性。

返回值

类型: System.WebIHttpHandler

示例:

public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
    Request request = new Request(context, requestType, url);
    if (!(request.Extension == Utility.HandlerExtension))
    {
        throw new HttpException(0x193, "The type of page you have requested is not served because it has been explicitly forbidden. The extension '." + request.Extension + "' may be incorrect. Please review the URL below and make sure that it is spelled correctly.");
    }
    if (context.Request["_session"] != null)
    {
        if (context.Request["_session"] == "rw")
        {
            return new AjaxHandlerSessionStateRW();
        }
        if (context.Request["_session"] == "r")
        {
            return new AjaxHandlerSessionStateR();
        }
        if (context.Request["_session"] == "no")
        {
            return new AjaxHandler();
        }
    }
    if ((context.Session != null) && !context.Session.IsCookieless)
    {
        return new AjaxHandler();
    }
    return new AjaxHandlerSessionStateR();
}