[转]ASP.NET应用程序生命周期趣谈(三) HttpModule
在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理。所有的HttpModule都要实现IHttpModule接口,那么我们看IHttpModule的定义:
namespace System.Web
{
public interface IHttpModule
{
void Dispose();
void Init(HttpApplication context);
}
}
可以看到,HttpModule主要就做了两件事,一个就是大家都明白的释放资源Dispose(),另一个则是初始化。用什么初始化呢?当然是HttpApplication。刚才已经说过,P_Module程序员是经过了项目经理HttpApplication的授权了的,这里我们就可以看到,初始化方法参数就是HttpApplication对象,那么HttpModule又是怎么处理应用程序级别的事件的呢?且看:
我们可以看到,项目经理HttpApplication可是实实在在的放权啊,它非常的相信P_Module可以做好这些事情,所以在初始化方法Init(HttpApplication context)中,程序员P_Module可以注册很多事件,比如说常用的BeginRequest, EndRequest, AuthenticateRequest, AuthorizeRequest等等,还有一些其它的不常用的事件我们就不再赘述。总而言之,HttpModule强大到可以插手整个应用程序周期的所有事件---因为得到了充分授权嘛。下面是注册BeginRequest事件示例代码:
public void Init(HttpApplication context)
{
context.EndRequest+= new EventHandler(context_EndRequest);
}
private void context_EndRequest(object sender, EventArgs e)
{
//do something when the request end
}
那么这里,我们要澄清一个问题:在ASP.NET应用程序生命周期趣谈(一)中我们曾经在后面提到“P_Handler自信的笑了一声,把箱子交还给了项目经理(HttpApplication对象)”,这是不完全准确的。事实上P_Module已经是一个非常高级的程序员,他在有必要的情况下(注册了EndRequest事件)是要review初级程序员P_Handler的工作的,这个review的事件就是HttpApplication的EndRequest的事件。当然,有时候也不review就直接交给HttpApplication了,所以我们得出结论:ASP.NET请求处理是基于管道模型的,request从管道这头进去,经过了HttpModule的一些列处理,到那头儿的HttpHandler再处理,最后再经过管道原路返回。一次请求HttpHandler只能有一个,而HttpModule却可以有若干个。(ps: --!真是废话,MSND上写的比谁都清楚)
总的来说,P_Module高级程序员主要就是从项目经理HttpApplication那得到授权(传入HttpApplication参数)处理应用程序级别的一些重要事件,这些事件贯穿整个应用程序生命周期。我们经常会使用到ASP.NET自带的HttpModule,也有时会使用自定义的HttpModule。ASP.NET自带的HttpModul在以下目录中可以找到:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG/web.config
而我们自己编写的自定义HttpModule则写在我们的应用程序的web.config文件中,也是<HttpModules></HttpModule>节点下,与系统自动配置的并无不同:
可以看到,<HttpModules>节点是在system.web下面的,HibernateUtil就是我曾经写过的一个HttpModule,非常典型,大家可以参考。对与系统自带的HttpModule有很多,这里我就随便挑了一个SessionStateModule来给大家做一个大致的分析,以便大家了解HttpModule如何工作。
简单说一下什么事SessionState。SessionState就是asp.net处理Session的一种机制,简单来说就是它通过管理Session的存储位置,来优化Session的性能和安全性,避免浏览器禁用cookie时session丢失。ASP.NET允许Session存储在三个位置:aspnet_wp.exe(它崩溃session就丢失);aspnet_state.exe(单独的stateserver);sqlserver(存到数据库中)。关于SessionState的内容,请参阅其它相关文章,以后有机会我自己也会写写。
书归正传,那么我们通过反编译SessionStateModule,我们得到两行有用的代码:
public void Init(HttpApplication app)
{
SessionStateSection sessionState = RuntimeConfig.GetAppConfig().SessionState;
//从config文件中读取SessionState配置
this.InitModuleFromConfig(app, sessionState);
//初始化SessionStateModule需要处理的事件
//Other Code
}
第一行从config文件中读取了SessionState的配置(节点<configuration><system.web><sessionState>下面的内容,配置了怎么存储Session等信息),第二行则初始化了SessionStateModule需要处理的事件,我们再看看InitModuleFromModule干了什么:
private void InitModuleFromConfig(HttpApplication app, SessionStateSection config)
{
if (config.Mode != SessionStateMode.Off)
{
app.AddOnAcquireRequestStateAsync(new BeginEventHandler(this.BeginAcquireState), newEndEventHandler(this.EndAcquireState));
app.ReleaseRequestState += new EventHandler(this.OnReleaseState);
app.EndRequest += new EventHandler(this.OnEndRequest);
}
}
我们可以看到,第一行代码中,HttpApplication添加了OnAcquireRequestState的若干事件的处理方法,第二行添加了当SessionState释放时的处理方法,第三行则添加了request接触时的处理方法。SessionStateModule内部如何处理我们这里不做详述,但是我们可以清晰的看到,SessionStateModule处理了应用程序级别的时间,包括SessionState的获得,释放和Request的结束。我们没有发现它处理开始Request的事件,但我们确信它是有能力去做的,只是此种情形下并不需要那么做。下面按照执行顺序列出HttpApplication的事件列表以供参考:
1. BeginRequest //开始
2. AuthenticateRequest //验证
3. AuthorizeRequest //授权
4. AcquireRequestState //获取request state
5. ReleaseRequestState //释放request state
6. UpdateRequestCache //更新cache
7. LogRequest. //这个事件只支持.net 3.0以上版本和IIS7的集成模式
8. EndRequest //结束
所有的HttpModule(包括自定义的和系统自带的)均有能力处理这些事件从而对应用程序产生影响,看来这个P_Module程序员果然很牛啊,项目经理信任它并授权也是有道理的。
然后P_Module作为一个高级程序员,它自身知识积累固然很强大,它的学习能力也是不可忽视的。它可以自己学习(创建)一些新的能力(自定义Module),经典的例子就是它网上盛传的它能在每个页面中都加入一些文字;这里我只简单的说明我用过的一个P_Module自建的在EndRequest事件中关闭NHibernateSession的例子:
首先,我们创建一个类HibernateUtil,继承接口IHttpModule,并实现接口方法:
public class HibernateUtil : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
}
}
然后,注册EndRequest事件:
public void Init(HttpApplication context)
{
context.EndRequest+= new EventHandler(context_EndRequest);
}
private void context_EndRequest(object sender, EventArgs e)
{
CloseSession();
}
最后,配置Web.config:
此时,我们就完成了一个自定义的HttpModule。这个小例子并不难,主要是说明了HttpModule的创建流程和方法,而本篇文章也难度也不是很高,希望对大家能有所帮助,欢迎拍砖,少扔鸡蛋,挺贵的,谢谢! ^_^
[转]ASP.NET应用程序生命周期趣谈(三) HttpModule的更多相关文章
- [转]ASP.NET应用程序生命周期趣谈(五) IIS7瞎说
Ps:建议初学者在阅读本文之前,先简要了解一下之前的几篇文章,以便于熟悉本文提到的一些关于IIS6的内容,方便理解.仅供参考. PS:为什么叫瞎说呢?我觉得自己理解的并不到位,只能是作为一个传声筒,希 ...
- [转]ASP.NET应用程序生命周期趣谈(一)
这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...
- [转]ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期
在之前的三篇文章中,我们还算简明扼要的学习了asp.net的整个生命周期,我们知道了一个Request进来以后先去ISAPI Filter,发现是asp.net程序后又ASPNET_ISAPI.dll ...
- [转]ASP.NET应用程序生命周期趣谈(二)
在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1, IIS肯定是没有眼睛 ...
- ASP.NET 应用程序生命周期
1.请求到达IIS服务器,IIS根据文件后缀找到对应的ISAPI(Internet Server API)扩展来处理,这个配置可在网站属性里的“根目录”选项卡中的“配置”里看到.可以看到,ashx.a ...
- asp.net应用程序生命周期和asp.net网页的生命周期
一.asp.net应用程序生命周期 asp.net应用程序生命周期以浏览器向web服务器(比如IIS服务器)发送请求为起点,先后经历web服务器下的ISAPI(Internet Server Appl ...
- asp.net应用程序生命周期
asp.net应用程序生命周期(流程文字描述版) 请求——>IIS——>ISAPI映射——>交给asp.net(即为IIS的扩展)——>通知Application类创建一个应用 ...
- ASP.NET 应用程序生命周期概述[转自MSDN]
本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段. 阶段 ...
- IIS 7.0 的 ASP.NET 应用程序生命周期概述(转载)
IIS 7.0 的 ASP.NET 应用程序生命周期概述更新:2007 年 11 月本主题介绍在 IIS 7.0 集成模式下运行以及与 IIS 7.0 或更高版本一起运行的 ASP.NET 应用程序的 ...
随机推荐
- java根据html生成摘要
转自:http://java.freesion.com/article/48772295755/ 开发一个系统,需要用到这个,根据html生成你指定多少位的摘要 package com.chendao ...
- 新应用上线 Snippet
Snippet 是一款代码片段收集工具,经过一天三夜的开发终于上线了. 应用地址:snippets.barretlee.com 源码地址:barretlee/snippets 由于使用原生 JS 开发 ...
- 简易nginx TCP反向代理设置
nginx从1.9.0开始支持TCP反向代理,之前只支持HTTP.这是我的系统示意图: 为何需要? 为什么需要反向代理?主要是: 负载均衡 方便管控 比如我现在要更新后端服务器,如果不用负载均衡的话, ...
- Linux C++ 开发简介
主要介绍将Windows程序迁移到Linux系统相关知识 简介 Windows程序迁移到Linux系统可能需要修改很多代码, 既需要了解Linux平台的开发知识, 也需要了解Windows平台代码如何 ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- Android Studio快捷键switch case 轻松转换为if else
Android Studio快捷键switch case 轻松转换为if else 今天碰到的问题,没有找到资料,后面找到了方法,这个记下来,转载请注明出处:http://www.cnblogs.co ...
- 安装过程错误[INS-30131]
问题:Oracle Database 安装过程错误[INS-30131] 原因:安装用户没有对临时文件夹的读写权限 解决方案: 1.以管理员身份运行cmd.exe 2.输入命令(需启动Se ...
- Linux进程管理及while循环
目录 进程的相关概念 进程查看及管理工具的使用 Linux系统作业控制 调整进程优先级 网络客户端工具 bash之while循环 20.1.进程类型 守护进程 daemon,在系统引导过程中启动的进程 ...
- 前端进阶试题(css部分)
一.css 40分 1. 什么是盒模型? 答: 2. Doctype的几种类型? 答:①.过渡的:②.严格的:③.框架的 更多详细介绍参考:资料 3. 如何布局左不动右边自适应的两列布局? 答:两种简 ...
- 04. Web大前端时代之:HTML5+CSS3入门系列~HTML5 表单
Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 一.input新增类型: 1.tel:输入类型用于应该包 ...