HttpRuntime打交道的是http协议跟IIS层面的东西,HttpApplication则具体到应用程序这一级别(也就是一个网站,这个跟web.config关系是基本一一对应的,像Module跟Handler的信息都是在这里定义),此时会生成相应的HttpContext(上下文信息,包括Request,Response等),在HttpApplication路由到具体的HttpHandler处理之时,HttpApplication的各个事件会被触发,而HttpModule则通过相应的事件如BeginRequest等来处理一些额外的事情,如UrlRewrite,缓存,安全验证等

管线(Pipeline)这个词也是很有点意思,这个词也形象地说明了每个Asp.net请求的处理过程: 请求是在一个管道中,要经过一系列的过程点,这些过程点连接起来也就形成一条线。 以上是我对于这个词的理解,如果有误,恳请给予指正。 这些一系列的过程点,其实就是由HttpApplication引发的一系列事件,通常可以由HttpModule来订阅, 也可以在Global.asax中订阅,这一系列的事件也就构成了一次请求的生命周期。

观察者模式:观察者模式定义了对象之间的一种联系,使得当一个对象改变状态时,其它对象会被相应的通知到。

Asp.net的管线设计正是采用了这种方式, 在这个设计模式中,观察者就是许多HttpModule对象,被观察的对象就是每一个请求,它的状态由HttpApplication控制,用于描述当前请求的处理阶段,

HttpApplication会根据一个特定的顺序修改这个状态,并在每个状态改变后引发相应的事件。 Asp.net会为每个请求分配一个HttpApplication对象来引发这些事件,因此可以让一大批观察者了解每个请求的状态, 每个观察者也可以在感兴趣的时候修改请求的一些数据。 这些与请求相关的数据的也就是HttpRequest, HttpResponse。

在处理该请求时将由 HttpApplication 类执行以下事件。 希望扩展 HttpApplication 类的开发人员尤其需要注意这些事件。
. 对请求进行验证,将检查浏览器发送的信息,并确定其是否包含潜在恶意标记。 有关更多信息,请参见 ValidateRequest 和脚本侵入概述。
. 如果已在 Web.config 文件的 UrlMappingsSection 节中配置了任何 URL,则执行 URL 映射。
. 引发 BeginRequest 事件。
. 引发 AuthenticateRequest 事件。
. 引发 PostAuthenticateRequest 事件。
. 引发 AuthorizeRequest 事件。
. 引发 PostAuthorizeRequest 事件。
. 引发 ResolveRequestCache 事件。
. 引发 PostResolveRequestCache 事件。
. 根据所请求资源的文件扩展名(在应用程序的配置文件中映射),选择实现 IHttpHandler 的类,对请求进行处理。 如果该请求针对从 Page 类派生的对象(页),并且需要对该页进行编译,则 ASP.NET 会在创建该页的实例之前对其进行编译。
. 引发 PostMapRequestHandler 事件。
. 引发 AcquireRequestState 事件。
. 引发 PostAcquireRequestState 事件。
. 引发 PreRequestHandlerExecute 事件。
. 为该请求调用合适的 IHttpHandler 类的 ProcessRequest 方法(或异步版 IHttpAsyncHandler.BeginProcessRequest)。 例如,如果该请求针对某页,则当前的页实例将处理该请求。
. 引发 PostRequestHandlerExecute 事件。
. 引发 ReleaseRequestState 事件。
. 引发 PostReleaseRequestState 事件。
. 如果定义了 Filter 属性,则执行响应筛选。
. 引发 UpdateRequestCache 事件。
. 引发 PostUpdateRequestCache 事件。
. 引发 EndRequest 事件。
. 引发 PreSendRequestHeaders 事件。
. 引发 PreSendRequestContent 事件。

对于这些管道事件

1.每个请求都将会映射到一个HttpHandler,通常也是处理请求的主要对象。

2.HttpModule可以任意订阅这些事件,在事件处理器中也可以参与修改请求的操作。

HttpHandler

HttpHandler通常是处理请求的核心对象。绝大多数的的请求都在【第10步】被映射到一个HttpHandler, 然后在【第15步】中执行处理过程,因此也常把这类对象称为处理器或者处理程序。我们熟知的Page就是一个处理器, 一个ashx文件也是一个处理器。

// 定义 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);
}

我们可以采用以下方式在web.config中注册一个自定义的处理器:

<httpHandlers>
<add path="/MyService.axd" verb="*" validate="false" type="MySimpleServiceFramework.MyServiceHandler"/>
</httpHandlers>

HttpModule

前面我已经提到过HttpModule的工作方式:订阅管线事件,并在事件处理器中执行所需的相关操作。
这个描述看起来很平淡,但是,它的工作方式给了它无限强大的处理能力。

它的无限强大的处理能力来源于可以订阅管线事件,因此,它有能力可以在许多阶段修改请求, 这些修改最终可能会影响请求的处理。
前面我说过:“HttpHandler是处理请求的主要对象”,但HttpModule却可以随意指定将某个请求交给某个处理器来执行!
甚至,HttpModule也可以直接处理请求,完全不给HttpHandler工作的机会!

public interface IHttpModule
{
void Dispose(); void Init(HttpApplication app);
}

在这二个方法中,第一个方法通常可以保持为空。最重要的方法就是Init,它给了HttpModule能订阅管线事件的机会, 然后在相应的事件处理中,我们就可以执行它的具体操作了。

<httpModules>
<add name="DuplexGzipModule" type="MySimpleServiceFramework.DuplexGzipModule"/>
</httpModules>

HttpModule的加载方式:ASP.NET会为每个请求分配一个HttpApplication对象,在每个HttpApplication对象的初始化操作中,它会加载所有在web.config中注册的HttpModule。由于Asp.net并不是只创建一个HttpApplication对象,而是多个HttpApplication对象, 因此每个HttpModule的Init事件是有可能被多次调用的。

关于HttpModule和HttpHandler以及HttpApplication的更多相关文章

  1. HttpHandler,HttpApplication, HttpModule

    选择HttpHandler还是HttpModule? HttpHandler和HttpModule之间有什么差别 之所以有这个疑问,是因为在这二类对象中都可以访问Request, Response对象 ...

  2. ASP.NET-自定义HttpModule与HttpHandler

    在之前的ASP.NET是如何在IIS下工作的这篇文章中介绍了ASP.NET与IIS配合工作的机制,在http请求经过一系列处理后,最后到达ASP.NET管道中,这时,就是Http Modules和Ht ...

  3. HttpModule与HttpHandler详解

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...

  4. Asp.net中的HttpModule和HttpHandler的简单用法

    在Asp.net中,HttpModule和HttpHandler均可以截取IIS消息进行处理,这使得我们制作人员能够非常方便的进行诸如图片水印添加,图片盗链检查等功能. 下面先就HttpModule的 ...

  5. HttpModule、HttpHandler和Page的生命周期

    1.引言 2.两个处理步骤 2.1.创建ASP.NET环境 2.2.用触发的MHPM事件处理请求 3.什么事件中应该做什么 4.示例代码 5.深入ASP.NET页面事件 1.引言 这篇文章我们将试图理 ...

  6. 002. Asp.Net Routing与MVC 之(基础知识):HttpModule 与 HttpHandler

    本文By 杨工. 一. Http.sys http.sys 从Win2003和WinXP SP2开始,就成为windows操作系统内核驱动程序,能够让任何应用程序通过它提供的接口,以http协议进行信 ...

  7. 转:HttpModule与HttpHandler详解

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...

  8. ASP.NET-自定义HttpModule与HttpHandler介绍

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...

  9. HttpModule与HttpHandler详解(转)

    ASP.NET对请求处理的过程:当请求一个*.aspx文件的时候,这个请求会被inetinfo.exe进程截获,它判断文件的后缀(aspx)之后,将这个请求转交给 ASPNET_ISAPI.dll,A ...

随机推荐

  1. linq基本操作

    一.Linq有两种语法: 1.  方法语法 2.  查询语法 下面举个例子看看这两种方法的区别 比如现在有一个学生类 public class student { public string user ...

  2. Confluence 6 安装 Oracle

    如果你还没有在安装可以连接的 Oracle 数据库,请先下载后进行安装.请参考 Oracle 文档 来获取有关安装的指南. 当你设置你的 Oracle 服务器的时候: 字符集 必须使用 AL32UTF ...

  3. Confluence 6 导入模板的步骤

    第一步:检查你 Confluence 站点中安装的模板组件 查看当前已经导入到你 Confluence 站点中可用的模板组件: 以系统管理员或者 Confluence 管理员权限登录 Confluen ...

  4. ES6之Set与Map加深理解

    Set 类似于数组,但是成员的值都是唯一的,没有重复的值,有序. Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化. 用途 数组去重: [...new ...

  5. linux和windows下,C/C++开发的延时函数,sleep函数

    简介: 函数名: sleep   功 能: 执行挂起一段时间   用 法: unsigned sleep(unsigned seconds);   在VC中使用带上头文件   #include < ...

  6. spring boot 解决跨域访问

    package com.newings.disaster.shelters.configuration; import org.springframework.context.annotation.B ...

  7. 《剑指offer》旋转数组中的最小数字

    本题来自<剑指offer> 旋转数组中的最小数字 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例 ...

  8. appium 手势

    1.2 appium玩转安卓手机 智能手机发展到今天,形成了一整套有关手势操作的操作习惯,如手指左右上下滑动,及双指缩放,还有手指的滑动解锁,摇晃手机等动作.那么我们怎么在python中利用appiu ...

  9. bat 获取拖放文件路径或名称

    获取路径: @echo offset path=%~dp1echo %path%pause 获取路径及名称: @echo offset path=%~dp1%~nx1echo %path%pause

  10. 数据结构C++实现代码-顺序表

    参考:https://blog.csdn.net/ebowtang/article/details/43094041 //seqList.h// //包含顺序表中的声明// #include<i ...