ASP.NET的底层体系2
文章引导
引言
接着上一篇ASP.NET的底层体系1我们继续往下走
一.System.Web.HttpRuntime.ProcessRequestInternal
我们看看ProcessRequestInternal的ProcessRequest
1.为请求创建一个新的HttpContext实例
2.获取一个HttpApplication实例
3.调用HttpApplication.Init()初始化管道事件
4.Init()触发HttpApplication.ResumeProcessing(),启动ASP.NET管道处理
一个新的HttpContext对象被创建,给它传递一个封装了ISAPI ECB的ISAPIWorkerRequest。HttpContext对象还包含一个非常有用的列表集合,你可以用它存储有关特定的请求需要的数据。上下文对象创建于一个请求生命周期的开始,在请求结束时被释放。因此保存在列表集合里的数据仅仅对当前的请求有效。
二.HttpApplication
每一个请求都将被路由到一个HttpApplication对象,HttpApplication类会为你的ASP.NET程序创建一个HttpApplication对象池,它负责加载程序和给每一个请求分发HttpApplication的引用,这个HttpApplication对象池的大小可以通过machine.config的ProcessModel节点中的MaxWorkerThreads选项配置。
HttpApplication对象池尽管以比较少的项目开始启动,但是同时有多个请求需要处理时,池中的对象也会随之增加。对于你的WEB程序而言,HttpApplication是一个外部容器,它对应到Global.asax文件定义的类。基于标准的web程序,它是你实际可以看到的HTTP运行时的第一个登录点。
HttpApplication主要用于HTTP管道的事件控制器,它的接口主要由事件构成。
BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequireState
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestState
EndRequest
每一个ASP.NET WEB程序运行在各自的AppDomain里,在AppDomain里同时运行着多个HttpApplication,这些实例存放在ASP.NET管理的一个HttpApplication对象池里。
观察AppDomain ID一致保持不变,而线程和HttpAapplication的ID在请求多的时候发生改变,这是因为HttpApplication是在一个集合里运行,下一个请求可能会再次使用同一个HttpApplication实例,所以有时候HttpApplication的ID会重复,一个HttpApplication实例对象并不依赖一个特定的线程,他们仅仅是被分配给处理当前请求的线程而已。
线程由.NET的ThreadPool提供服务,默认情况下,线程模型为多线程单元(MTA),你可以通过在ASP.NET的页面的@Page指令里设置属性ASCOMPAT="true"覆盖线程单元的状态。ASPCOMPAT意味着COM组件将在一个安全的环境下运行。实际上,这些HttpApplication对象运行在同一个AppDomain里是很重要的,这就是Asp.net如何保证web.config的改变或者单独的ASP.NET页面得到验证可以贯穿整个AppDomain。改变web.config的值导致AppDomain的重新开启。这确保了所有的HttpApplication实例可以看到这些改变,这是因为当AppDomain重新加载的时候,来自ASP.NET的那些改变将会在AppDomain启动的时候重新读取,当AppDomain重新启动的时候任何静态的引用都将重新加载。
这些改变将引起Web程序重新启动,对于已经存在于处理管道的请求,将继续通过原来的管道处理,而对于那些新的请求,将被路由到新的AppDomain里,为了处理这些“挂起的请求”,在这些请求超时结束之后,ASP.NET将强制关闭AppDomain甚至这些请求该没有处理。因此在一个特定的时间上,同一个HttpApplication实例在两个AppDomain里存在是有可能的。
HttpApplication负责请求的传输,通过触发事件,通知应用程序正在发生的事情。这个是作为HttpApplication.Init()方法的一部分实现的(System.Web.HttpApplication.InitInternal和HttpApplication.ResumeSteps())。在这个方法里,创建和启动了一系列事件,包括绑定事件处理器,Global.asax里的事件处理器会自动映射到对应的事件。
通过在web.config里注册,HttpModules和HttpHandlers可以被动态的加载,并且可以添加到事件链条上,HttpModules实际就是事件处理器,可以勾住指定的HttpApplication的事件,而HttpHandlers就是一个端点,可以被调用处理“应用程序级的请求处理”。
HttpApplication本身不知晓发送给WEB程序的数据,它只是个跑腿的,它是个事件的容器,负责事件之间的通信,传递HttpContext对象。
ASP.NET管道一旦成功,HttpApplication将逐一触发事件,每一个事件将被触发,如果事件绑定了事件处理器,那么这些事件处理器将被调用,执行他们的任务。这个过程的目的是通过调用HttpHandler处理指定的请求,对于ASP.NET而言,HttpHandler是处理请求机制的核心。ASP.NET的页面和web Service都是HttpHandler的具体实现。HttpModule倾向于在分发给事件处理器之前和之后对内容进行处理
三.HttpModule
模块的本质是过滤器,在功能上类似ASP.NET请求级别的ISAPI过滤,对于每一个穿过ASP.NET的HttpApplication对象的请求,模块都允许在HttpApplication对象触发的事件处理方法里截获这些请求,这些模块以类的形式存储在外部程序集里,可以在web.config里配置。当程序启动的时候加载,通过实现指定的接口和方法,模块就可以被添加在HttpApplication的事件链上,多个HttpModules可以勾住相同的事件,事件发生的顺序跟他们在web.confg里配置顺序。
<configuration>
<sysytem.Web>
<HttpModules>
<add name="BasicAuthModule" type="HttpHandlers.BasicAuth,WebStore"/>
模块允许你查看每一个传入的web请求,基于触发的事件基础上执行操作。模块是非常有用的,它可以修改请求,输出响应的内容以及提供自定义的身份验证。另外可以在特定的程序里,针对ASP.NET的每一个请求提供响应前处理和响应后处理。
HttpModule类似ISAPI的感觉,由于他们查看进入ASP.NET程序的每一个请求,但它们的局限性仅查看映射到某一个ASP.NET程序或虚拟目录的请求和映射到ASP.NET的请求,因此你可以查看所有的ASPX页面或者任意其他自定义的已经映射到这个程序的扩展名。
实现一个HttpModule模块,它包含两个方法:Init()和Dispose(),传递的事件参数中包含一个HttpApplication对象的引用,它会给你HttpContext的访问权限。
public class BasicAuthCustomModule : IHttpModule
{ public void Init(HttpApplication application)
{
// *** Hook up any HttpApplication events
application.AuthenticateRequest +=
new EventHandler(this.OnAuthenticateRequest);
}
public void Dispose() { } public void OnAuthenticateRequest(object source,
EventArgs eventArgs)
{
HttpApplication app = (HttpApplication) source;
HttpContext Context = HttpContext.Current;
… do what you have to do… }
}
在Init()方法里,你可以勾住多个事件,因此在一个模块里,可以管理多个不同功能的操作。在HttpModules里使用HttpApplication的事件时,Response.End()和HttpApplication.CompleteRequest()方法会使ASP.NET跳过HttpApplication和模块的事件链。
四.HttpHandler
HttpModule针对每一个传入ASP.NET程序的请求触发,HTTPHandler重于处理一个指定的请求映射。HttpHandler继承IHttpHandler,这个借口有一个方法ProcessReuqest()和一个属性IsReusable。ProcessRequest()可以获取一个HttpContext。
HttpHandler的关键操作是往Response对象里写输出数据,或者更确切的说,是往Response对象的OutputStream里写,这个就是真正返回到客户端的输出数据,在底层,由ISAPIWorkerRequest负责把OutputStream发回给ISAPI的ecb.WriteClient方法,因为ecb.WriteClient才是真正执行IIS产生输出数据的。
ASP.NET的底层体系2的更多相关文章
- ASP.NET的底层体系1
文章引导 1.ASP.NET的底层体系1 2.ASP.NET的底层体系2 引言: 学习ASP.NET,要想做的更好,不了解ASP.NET是不行的.一个有理想的程序员都会像挤压海绵一样,努力的去学习和获 ...
- 窥探ASP.Net MVC底层原理 实现跨越Session的分布式TempData
1.问题的引出 我相信大家在项目中都使用过TempData,TempData是一个字典集合,一般用于两个请求之间临时缓存数据或者页面之间传递消息.也都知道TempData是用Session来实现的,既 ...
- ASP.NET MVC底层原理与框架
前言 鄙人有一毛病,喜欢钻研原理性的东西,感觉只知道怎么用还不太够,更想知道如何实现的以及为什么会这样. 暑假的时候做积分系统是第一次接触MVC,感觉MVC就是一个框架,分为Module ,view和 ...
- 【转】从底层了解ASP.NET体系结构
从底层了解ASP.NET体系结构 原文:http://blog.csdn.net/zhoufoxcn/article/details/1890158 Java体系架构的书多如牛毛,比如SSH架构什么的 ...
- (翻译)从底层了解ASP.NET体系结构 [转]
转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...
- 【转】(翻译)从底层了解ASP.NET体系结构
原文地址:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言关于ASP.NET的底层的工作机制,最近园 ...
- ASP.NET底层与各个组件的初步认识与理解 (转载)
ASP.NET底层的初步认识与理解 最近在国外的网站乱走一通,发现一些比较好的文章,收集整理加于自己的理解,作为笔记形式记录下来,让以后自己有个回忆. ASP.NET是一个非常强大的构建Web应用 ...
- 从底层了解ASP.NET体系结构
导读: 前言 关于ASP.NET的底层的工作机制,最近园子里讨论的甚是火热.相信很多人都看过Rick Strahl先生的一篇经典之作:A low-level Look at the ASP.NET ...
- 学习ASP.NET Core,你必须了解无处不在的“依赖注入”
ASP.NET Core的核心是通过一个Server和若干注册的Middleware构成的管道,不论是管道自身的构建,还是Server和Middleware自身的实现,以及构建在这个管道的应用,都需要 ...
随机推荐
- Algo: Binary search
二分查找的基本写法: #include <vector> #include <iostream> int binarySearch(std::vector<int> ...
- d3创建多个svg元素
当然也可以创建dom var svg = d3.select('#svg'); svg .slectAll('circle.bb') //选中DOM中的所有circle.bb标签,当DOM中不 ...
- SPOJ:[DIVCNT3]Counting Divisors
题目大意:求1~N的每个数因子数的立方和. 题解:由于N过大,我们不能直接通过线性筛求解.我们可以采用洲阁筛. 洲阁筛的式子可以写成: 对于F(1~√n),可以直接线性筛求解. 对于,我们进行以下DP ...
- NX二次开发-创建CSYS坐标系UF_CSYS_create_csys
NX9+VS2012 #include <uf.h> #include <uf_csys.h> #include <uf_mtx.h> UF_initialize( ...
- 2018-06-05(thinking in java)
1:类只能有2种访问权限,一种是不写访问权限:默认包访问权限,另一种是public.且类只能有一个pubic 2:方法有4种访问权限,pubic(都可以访问),protexted(继承访问权限),pr ...
- scanf 与getchar区别
#include<stdio.h> void main() { int c; c=getchar(); //scanf("%c",&c); if(c!=' ...
- eclipse导入别人项目配置tomcat和jdk
1.file--import--General--Existing Projiect into Workspace-- 2.导入项目成功后,项目会有错误,需重新进行tomcat及jdk的配置 项目名右 ...
- javascript es6 语法快速入门
1. let.const 作用:let 声明变量,const 声明常量 与 var 的区别:不能重复声明,且存在块级作用域,即只在代码块内生效 2. 箭头函数 使用: let show = funct ...
- jQuery Ajax请求 .net 一般处理程序
初学ajax 一个简单的功能,调试了2个小时,代码如下虽然成功了 但是有错误 <!DOCTYPE html> <html> <head> <meta http ...
- 1-电脑C盘(系统盘)清理
推荐,亲测有效! 转自: https://baijiahao.baidu.com/s?id=1612762644229315967&wfr=spider&for=pc