HttpModule、HttpHandler和Page的生命周期
- 1、引言
- 2、两个处理步骤
- 2.1、创建ASP.NET环境
- 2.2、用触发的MHPM事件处理请求
- 3、什么事件中应该做什么
- 4、示例代码
- 5、深入ASP.NET页面事件
1、引言
这篇文章我们将试图理解,从用户发送一个请求直到请求呈现到浏览器发生的事件的差异。因此,我们首先将介绍解ASP.NET请求的两个概括的步骤,接下来我们将介绍‘HttpHandler’,‘HttpModule’和ASP.NET页面对象发出的事件的差异。随着我们的事件旅程,我们将理解这些事件的逻辑。
2、两个处理步骤
ASP.NET请求处理可以总结为如下所示的两个处理步骤。用户发送一个请求到IIS:
- ASP.NET创建处理请求的环境。换句话说,创建应用程序对象、request、response和context对象去处理请求。
- 一旦环境已经创建,请求通过使用modules、handlers和page对象的一系列事件处理。为了简化可以称为MHPM(module、handler、page、module event),我们将在后面详细讨论。

图1、ASP.NET请求处理的两个步骤
在接下来的各节,我们将知道更多关于这两个步骤的细节。
2.1、创建ASP.NET环境
step 1:用户发送一个请求到IIS。IIS首先检查哪个ISAPI扩展可以处理这个请求,这取决于请求的文件扩展名。举例来说,如果请求页面是‘.ASPX’,它将被传送到‘aspnet_isapi.dll’来处理。
step 2:如果这是www站点的第一个请求,ApplicationManager类将创建一个应用程序域,www站点运行于其中。我们都知道在同一个IIS上,两个web应用程序的应用程序域是独立的(隔离的)。因此一个应用程序域中问题不会的影响到其它应用程序域。
step 3:新建的应用程序域创建宿主环境,如HttpRuntime对象。一旦宿主环境被创建,必要的ASP.NET核心对象如HttpContext、HttpRequest和HttpRespone对象也被创建。
step 4:一旦所有的ASP.NET核心对象被创建,HttpApplication对象将被创建去处理请求。如果系统中有global.asax文件,global.asax文件对象将被创建。请注意:global.asax文件继承自HttpApplication类。
注意:第一次ASP.NET页面连接到应用程序,一个HttpApplication新实例将被创建。为了最大化性能,HttpApplication实例可能被多个请求重用。
step 5:接下来HttpApplication对象分配给核心ASP.NET对象来处理页面。
step 6:然后HttpApplication通过HttpContext、HttpRequest和HttpRespone事件开始处理请求。它触发MHPM事件处理请求。更多细节

图2、创建ASP.NET环境
下图解释了ASP.NET请求的内部对象模型。最高层是ASP.NET运行时,它已经创建一个应用程序域(AppDomain),相应地有HttpRuntime包括request、respone、context对象。
图3、ASP.NET请求的内部对象模型
2.2、用触发的MHPM事件处理请求
一旦创建了HttpApplication,它开始处理请求,它经历3个不同的部分HttpModule、Page、HttpHandler。随着它移动到这些部分,将调用不同的事件,开发人员可以扩展和定制同一逻辑。在我们前进之前让我们了解什么是HttpModule和HttpHandlers。他们帮组我们在ASP.NET页处理的前后注入自定义逻辑。他们之间的主要差别是:
- 如果你想要注入的逻辑是基于像‘.ASPX’、‘.HTML’这样的文件扩展名,使用HttpHandler。换句话说HttpHandler是基于处理器的扩展。

- 如果你想在ASP.NET管道事件中注入逻辑,使用HttpModule。换言之是基于处理器的事件。

你可以点这了解他们之间更多的差异。下面是怎样处理请求的逻辑流。有四个重要的步骤MHPM,解释如下:
Step 1(M HttpModule):客户端请求处理开始。ASP.NET引擎开始和创建HttpModule发出事件(你可以注入定制逻辑)之前,有6个重要事件你可以使用:BeginRequest、AuthenticateRequest、AuthorizeRequest、ResolveRequestCache、AcquireRequestState和PreRequestHandlerExecute。
Step 2(H HttpHandler):一旦上面6个事件触发,ASP.NET引擎将调用ProcessRequest事件,即使你已经在项目中执行了HttpHandler。
Step 3(P ASP.NET page):一旦HttpHandler逻辑执行,ASP.NET page对象被创建。ASP.NET page对象被创建,许多事件被触发,你可以在这些页面事件中写我们自定义的逻辑。有6个重要事件给我们提供占位,在ASP.NET页中写逻辑:Init、Load、Validate、Event、Render、Unload。你可以记住单词SILVER来记这些事件,S-Start(没有任何意义,仅仅是为了形成一个单词),I(Init)、L(Load)、V(Validate)、E(Event)、R(Render)。
Step 4(M HttpModule):一旦页面对象执行了且从内存中卸载,HttpModule提供发送页面执行事件,它们可用于注入自定义post-处理逻辑。有4个重要的post-处理事件,PostRequestHandlerExecute、PostRequestState、UpdateRequestCache、EndRequest。
下图展示了上面的过程。

3、什么事件中应该做什么
下面的表格展示了什么事件中做什么逻辑或代码。
| Section | Event | Description |
| HttpModule | BeginRequest | 此事件标志着一个新的请求,他保证在每个请求中都有。 |
| HttpModule | AuthenticateRequest | 此事件标志ASP.NET运行时准备验证用户。任何身份验证代码都可以在此注入。 |
| HttpModule | AuthorizeRequest | 此事件标志ASP.NET运行时准备授权用户。任何授权代码都可以在此注入。 |
| HttpModule | ResolveRequest | 在ASP.NET中我们通常使用OutputCache指令做缓存。在这个事件中,ASP.NET运行时确定是否能够从缓存中加载页面,而不是从头开始生成。任何缓存的具体活动可以被注入这里。 |
| HttpModule | AcquireRequestState | 此事件标志着ASP.NET运行时准备获得会话变量。可以对会话变量做任何你想要的处理。 |
| HttpModule | PreRequestHandlerExecute | 恰好在ASP.NET 开始执行事件处理程序前发生。可以预处理你想做的事。 |
| HttpHandler | ProcessRequest | HttpHandler逻辑被执行。在这个部分我们将为每个页面扩展名写需要的逻辑。 |
| Page | Init | 此事件发生在ASP.NET页面且可以用来: 1、动态地创建控件,如果你一定要在运行时创建控件; 2、任何初始化设置 3、母版页及其设置 在这部分中我们没有获得viewstate、postedvalues及已经初始化的控件。 |
| Page | Load | 在这部分ASP.NET控件完全被加载且在这里你可以写UI操作逻辑或任何其他逻辑。 |
| Page | Validate | 如果在页面上你有验证器,你同样想在这里检查。 |
| Page | Render | 是时候将输入发送到浏览器。如果你想对最终的HTML做些修改,你可以在这里输入你的HTML逻辑。 |
| Page | Unload | 页面对象从内存中卸载。 |
| HttpModule | PostRequestHandlerExecute | 可以注入任何你想要的逻辑,在处理程序执行之后。 |
| HttpModule | ReleaseRequestState | 想保存更新某些状态变量,如会话变量。 |
| HttpModule | UpdateRequestCache | 在结束之前是否更新你的缓存。 |
| HttpModule | EndRequest | 这是将输出发送到客户端浏览器之前的最后一个阶段。 |
4、示例代码
点击下载代码,示例代码展示了事件是怎样触发的。代码中我们创建了一个HttpModule和HttpHandler,且我们显示一个简单的响应在所有的事件中。下面是HttpModule类,跟踪所有的事件且添加到全局集合。
HttpModule类
下面是HttpHandler的代码片段,它跟踪ProcessRequest事件。
HttpHandler代码片段
我们也追踪ASP.NET页面的所有事件。
asp.net页面事件
下面显示上面讨论的所有事件的执行顺序:

5、深入ASP.NET页面事件
在前面部分我们已经知道ASP.NET页面请求的整体事件流,但是我们没有详细讨论,因此本节我们将深入了解。任何ASP.NET页面有2个部分,一个是显示在浏览器上的页面,它有HTML标记、viewstate形式的隐藏值、HTML inputs上的数据。当页面被发送时,在服务器上这些HTML标记被创建到ASP.NET控件且viewstate和表单数据捆绑在一起。一旦你得到这些服务器控件的后台代码,你可以执行和写你自己的逻辑和呈现返回给浏览器。
现在这些HTML控件在服务器上作为ASP.NET控件,ASP.NET页面发出一些事件,我们可以注入自己的逻辑。根据任务/你要执行的逻辑,我们需要把这些逻辑放入适当的事件中。
注意:大部分开发者直接使用Page_Load方法执行一切,这不是一个好的方法。因此,不是填充控件、设置viewstate、应用主题等一切都发生在页面加载上。因此,如果我们能在适当的事件中放入逻辑,将真正使你的代码干净。
| Seq | Events | 控件初始化 | Viewstate可用 | 表单数据可用 | 什么逻辑可以写在这里? |
| 1 | Init | No | No | No | 注意:你可以通过使用ASP.NET请求对象访问表单数据等,但是不是通过服务器控件。 动态地创建控件,如果你一定要在运行时创建;任何初始化设置;母版页及其设置。在这部分中我们没有获得viewstate、postedvalues及已经初始化的控件。 |
| 2 | Load View State | Not guaranteed | Yes | Not guaranteed | 你可以访问View State及任何同步逻辑,你希望viewstate被推倒后台代码变量可以在这里完成。 |
| 3 | PostBackdata | Not guaranteed | Yes | Yes | 捏可以访问表单数据。任何逻辑,你希望表单数据被推倒后台代码变量可以在这里完成。 |
| 4 | Load | Yes | Yes | Yes | 在这里你可以放入任何你想操作控件的逻辑,如从数据库填充combox、对grid中的数据排序等。这个事件,我们可以访问所有控件、viewstate、发送的值。 |
| 5 | Validate | Yes | Yes | Yes | 如果你的页面有验证器或者你想为你的页面执行验证,那就在这里做吧。 |
| 6 | Event | Yes | Yes | Yes | 如果这是通过点击按钮或下拉列表的改变的一个回发,相关的事件将被触发。与事件相关的任何逻辑都可以在这里执行。 |
| 7 | Pre-render | Yes | Yes | Yes | 如果你想对UI对象做最终的修改,如改变属性结构或属性值,在这些控件保存到ViewState之前。 |
| 8 | Save ViewState | Yes | Yes | Yes | 一旦对服务器控件的所有修改完成,可以保存控件数据到View State。 |
| 9 | Render | Yes | Yes | Yes | 如果你想添加一些自定义HTML到输出,可以在这里完成。 |
| 10 | Unload | Yes | Yes | Yes |
做任何你想做的清理工作。 |

HttpModule、HttpHandler和Page的生命周期的更多相关文章
- Page的生命周期及相关事件苛
(1)请求页面:页请求发生在页生命周期开始之前. (2)开始:在开始阶段,将设置页属性,如Request和Response.在此阶段,页还将确定请求是回发请求还是新请求,并设置IsPostBack属性 ...
- Page 的生命周期学习小结(翻译兼笔记)
初始化(Initialization) 页面被请求时,第一个被执行的总是下面接着执行的是 接着是 然后是 恢复和加载(Restore and Load) 接下来的 ViewState 被取回后,接着 ...
- 小程序page中生命周期
onLoad -- 页面被加载出来 onShow -- 页面显示出来后 退出后两小时进来,只会执行这个生命周期 onRady -- (逻辑层传给渲染层后才会执行)监听页面初次渲染完成 onHide ...
- 微信小程序page的生命周期和音频播放及监听
一.界面的生命周期 /** * 监听页面加载, * 页面加载中 */ onLoad:function(){ var _this = this console.log('index---------on ...
- Page页面生命周期——微信小程序
onLoad:function (options) { //页面初始化 console.log('index Load') }, onShow:function () { // ...
- 《微信小程序七日谈》- 第三天:玩转Page组件的生命周期
<微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 前两篇 ...
- ASP.NET 管道事件与HttpModule, HttpHandler简单理解 -摘自网络
第一部分:转载自Artech IIS与ASP.NET管道 ASP.NET管道 以IIS 6.0为例,在工作进程w3wp.exe中,利用Aspnet_ispai.dll加载.NET运行时(如果.NET ...
- Asp.Net生命周期系列二
在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1, IIS肯定是没有眼睛 ...
- ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期
开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计.本篇,我们来看看WebForm模式下的页面生命周期. ( ...
随机推荐
- Notepad++使用技法
Alt+H 隐藏行 Ctrl+Tab 实现在多个打开的窗口间切换 Ctrl+Shift+Q区块注释 Ctrl+K行注释(取消Ctrl+Shift+K) 文件 新建文件 Ctrl+N 打开文件 C ...
- codeforces 632F. Magic Matrix
题目链接 给一个n*n的矩阵, 问是否对角线上的元素全都为0, a[i][j]是否等于a[j][i], a[i][j]是否小于等于max(a[i][k], a[j][k]), k为任意值. 前两个都好 ...
- android小知识之圆角ListView
有些东西看多了,就厌烦了:extjs对我这种感觉最为强烈.甚至,有时觉得设计之殇是审美疲劳.直角看多了,就想看看圆角,不知何时,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,iphone中 ...
- 深信服模式(先做减法,必须拜访客户三次、研究需求方向,把产品的问题控制住,快速反应,在未来十年,绝大部分业务都会搬到Internet上来,实现All on Internet)good
深圳市盛凯信息科技有限公司与深信服合作多年,可以说是看着深信服“飞速”长大的.盛凯的总经理邓渊在采访中笑言:“他们(深信服)发展得太快,而我们发展得太慢.” 深信服的产品线已从最初只有VPN一条,到目 ...
- Qt限制文本框输入的方法(使用QRegExpValidator,为QLineEdit所独有)
在做界面编程的时候,对文本框的处理往往是个很头疼的事情,一是焦点进入文本框时,从人性化考虑,应选择文本框中文本,方便输入:二是,限制文本框的输入,只允许输入有效的文本,如果不这样做的话,那么就需要在程 ...
- flume 日志采集工具
Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并 ...
- TCP/IP笔记 三.运输层(2)——TCP 流量控制与拥塞控制
TCP 的流量控制与拥塞控制可以说是一体的.流量控制是通过滑动窗口实现的,拥塞避免主要包含以下2个内容: (1)慢开始,拥塞避免 (2)快重传,快恢复 1.流量控制——滑动窗口 TCP采用大小可变的滑 ...
- MyMVC框架的使用
1)在web.config 中system.web 节点下加入例如以下代码 <pages controlRenderingCompatibilityVersion="4.0" ...
- iPhone开发之全局变量的使用
全局变量历来就是很好的东西,能够在开发中带来很多方便,下面来介绍一下iPhone中软件开发时全局变量的使用方法: 一.新建Constants.h文件(文件名根据需要自己取),用于存放全局变量: 二.在 ...
- JavaScript之将JS代码放在什么位置最合适
1.放到<head></head>标签里面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/ ...