(转)Asp.Net生命周期系列三
原文地址:http://www.cnblogs.com/skm-blog/p/3178862.html
上文讲到了HttpRunTime主要做了三个事情,我们先回忆一下。
第一:雇佣了项目经理(HttpApplication)。
第二:建立了HttpModule列表,项目经理(HttpRunTime)就是按照这个工作列表去工作的。
第三:创建了Context上下文对象(包含了HttpRequest和HttpResponse两大主要对象),并把它转交给了HttpApplication去处理。
下面最重要的是HttpModule到底是个什么东东,HttpApplication又是怎么样按照它的工作列表去工作的。
当一个请求到达HttpModule时,整个Asp.Net系统并没有对这个Http请求做任何的处理,对于一个Http请求,HttpModule是这个请求的必经之路{Asp.Net内部的处理模型是一个管道流,也就是用户发出一个Http请求一定会从HttpModule这个容器中流过},所以我们可以在Http请求真正到达请求处理中心(HttpHandler)之前,添加一些需要的信息在这个Http请求上、或者针对截获的这个Http请求添加一些额外的工作,再或者干脆终止此次Http请求。可见HttpModule就相当于起到一个Filter过滤器的作用。
1、asp.net的HTTP请求处理过程
![]()
说明:
(1)、客户端浏览器向服务器发出一个http请求,此请求会被inetinfo.exe进程 截获,然后转交给aspnet_isapi.dll进程,接着它又通过Http Pipeline的管道,传送给aspnet_wp.exe这个进程,接下来就到了.net framework的HttpRunTime处理中心,处理完毕后就发送给用户浏览器。
(2)、当一个 http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入 到如下几个容器中:HttpModule --> HttpHandler Factory --> HttpHandler。当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成了,客户端也就得到相应的东东了。
(3)完整的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()
也就是说一个HTTP请求在HttpModule容器的传递过程中,会在某一时刻(ResolveRequestCache事件)将这个HTTP请 求传递给HttpHandler容器。在这个事件之后,HttpModule容器会建立一个HttpHandler的入口实例,但是此时并没有将HTTP 请求控制权交出,而是继续触发AcquireRequestState事件以及PreRequestHandlerExcute事件。在 PreRequestHandlerExcute事件之后,HttpModule窗口就会将控制权暂时交给HttpHandler容器,以便进行真正的 HTTP请求处理工作。
而在HttpHandler容器内部会执行ProcessRequest方法来处理HTTP请求。在容器HttpHandler处理完毕整个 HTTP请求之后,会将控制权交还给HttpModule,HttpModule则会继续对处理完毕的HTTP请求信息流进行层层的转交动作,直到返回到 客户端为止。
2、HttpModule的工作原理
HttpModule实现了IHttpModule接口,我们可以定义自己类实现IHttpModule接口,从而把我们自己定义的HttpModule插入到HttpModule集合中让它成为Http请求的必经之路,以此来添加我们的控制。
asp.net自带的HttpModule如下:具体位置在C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG文件中

<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/>
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/>
<add name="RoleManager" type="System.Web.Security.RoleManagerModule"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/>
<add name="AnonymousIdentification" type="System.Web.Security.AnonymousIdentificationModule"/>
<add name="Profile" type="System.Web.Profile.ProfileModule"/>
<add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
<add name="ServiceModel" type="System.ServiceModel.Activation.HttpModule, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</httpModules>

这里的每个HttpModule在一个Http请求过来时都会流过。
3、我们可以定义自己的HttpModule
要变成HttpModule就必须实现IHttpModule接口,那么我们先来看看IHttpModule接口的内部是什么样的

using System;
namespace System.Web
{
public interface IHttpModule
{
// 销毁不再被HttpModule使用的资源
void Dispose();
// 初始化一个Module,为捕获HttpRequest做准备
void Init(HttpApplication context);
}
}

下面是自己定义的HttpModule

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace ClassLibrary1
{
public class MyHttpModel:IHttpModule
{ public void Dispose()
{
throw new NotImplementedException();
} public void Init(HttpApplication context)
{
context.BeginRequest+=new EventHandler(context_BeginRequest);
context.EndRequest+=new EventHandler(context_EndRequest);
}
public void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
HttpResponse response = context.Response;
response.Write("这是自定义的HttpModel中的BeginRequest事件产生的。");
}
public void context_EndRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;
HttpContext context = application.Context;
HttpResponse response = context.Response;
response.Write("这是自定义的HttpModel中的EndRequest事件产生的。");
}
}
}

置文件如下
<httpModules>
<add name="MyHttpModel" type="ClassLibrary1.MyHttpModel,ClassLibrary1"/>
</httpModules>
请求的Default.aspx.cs文件如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace ClassLibrary1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("这是Default.aspx页面请求的内容信息。");
}
}
}

具体运行结果如下:
今天就写到这里吧,文章页有些长了,不过HttpModule还没有介绍完呢,如果您对我的文章感兴趣的话请继续关注我的下篇,下篇我们将继续介绍HttpModule这个东东的。
本系列:
(转)Asp.Net生命周期系列三的更多相关文章
- Asp.Net生命周期系列三
上文讲到了HttpRunTime主要做了三个事情,我们先回忆一下. 第一:雇佣了项目经理(HttpApplication). 第二:建立了HttpModule列表,项目经理(HttpRunTime)就 ...
- Asp.Net生命周期系列四
上回我们说的当一个Http请求来到HttpModule这里的时候,Asp.Net内部并未对这个Http请求做出任何的处理,我们可以对这个Http请求添加一些我们需要的信息,以方便我们控制这个Http请 ...
- Asp.Net生命周期系列五
如果您看了我的前四篇文章,应该知道目前Http请求已经流到了HttpModule这个程序员手中了,而且我们可以注册自己的HttpModule并且可以在里面注册一些事件来控制这个Http请求,但是到目前 ...
- (转)Asp.Net生命周期系列五
原文地址:http://www.cnblogs.com/skm-blog/p/3188697.html 如果您看了我的前四篇文章,应该知道目前Http请求已经流到了HttpModule这个程序员手中了 ...
- Asp.Net生命周期系列二
在上回书开始的时候我们提到博客园的IIS看了一眼我的请求后就直接交给ASP.NET去处理了,并且要求ASP.NET处理完之后返回HTML以供展示. 那么我们不仅要问: 1, IIS肯定是没有眼睛 ...
- Asp.Net生命周期系列六
上篇说到当一个Http请求流到HttpHandler这里时才开始对它的处理,那么一个请求经过HttpHandler之后, 到底怎么对它处理呢,也就是说HttpHandler会触发哪些事件,触发的顺序如 ...
- (转)Asp.Net生命周期系列一
原文地址:http://www.cnblogs.com/skm-blog/archive/2013/07/07/3176713.html Asp.Net生命周期对于初级甚至中级程序员来说,一直都是一个 ...
- Asp.Net生命周期系列一
Asp.Net生命周期对于初级甚至中级程序员来说,一直都是一个难题,很多程序员不了解生命周期,导致使用Asp.Net做开发感觉很不灵活,感觉太多东西被微软封装好了,我们不能改变,其实只要你稍微了解一下 ...
- ASP.NET生命周期详解
最近一直在学习ASP.NET MVC的生命周期,发现ASP.NET MVC是建立在ASP.NET Framework基础之上的,所以原来对于ASP.NET WebForm中的很多处理流程,如管道事件等 ...
随机推荐
- python 函数 hex()
hex(x)作用:hex() 函数用于将10进制整数转换成16进制整数. x-10进制整数,返回16进制整数 实例: >>>hex(255) '0xff' >>> ...
- Ambari的资源池管理
操作: YARN→Config→Advanced→Schedule capacity-scheduler=null yarn.scheduler.capacity.default.minimum-us ...
- Ubuntu15.10下Hadoop2.6.0伪分布式环境安装配置及Hadoop Streaming的体验
Ubuntu用的是Ubuntu15.10Beta2版本,正式的版本好像要到这个月的22号才发布.参考的资料主要是http://www.powerxing.com/install-hadoop-clus ...
- etcd使用经历
etcd是一个开源的.分布式的键值对数据存储系统,提供共享配置.服务的注册和发现.etcd与zookeeper相比算是轻量级系统,两者的一致性协议也一样,etcd的raft比zookeeper的pax ...
- zabbix监控的配置
ZABBIX监控的操作步骤有两个! 首先登录到zabbix 的主界面在configuration---host---create host在如上的host 创建界面中 主要是输入被监测的server的 ...
- SpringCloud子项目
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全 ...
- java内存基础(一)
博客园 闪存 首页 新随笔 联系 管理 订阅 随笔- 35 文章- 0 评论- 29 关于Java 数组内存分配一点认识 //总结:[ 数组引用变量存储在栈内存中,数组对象存储在堆内存当中.数 ...
- 1078 Hashing
题意:给出表长和待插入的元素,求每个元素的插入位置,散列函数为H(key)=key%TSize,解决冲突利用平方探测法(只考虑正向偏移). 思路:同1145 Hashing - Average Sea ...
- php无刷新上传图片
1. 引入文件 <!--图片上传begin--> <script type="text/javascript" src="/js/jquery.form ...
- python's twenty-sixth day for me 模块
configparser 模块: 该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键 = 值). 创建文件: # 创建文件 i ...