原文:http://www.cnblogs.com/cilence/archive/2012/05/28/2520712.html

Asp.Net 请求处理机制
 
前言
我们都知道Web请求响应是基于Http协议,那么我们可以这样来理解,一次Web请求和响应的过程,实际上就是一次发送Http请求和接收Http响应的过程。
客户端向服务器发送一次Http请求,服务器端接收到这次请求,并生成响应报文
,将响应报文发送回客户端。这样客户端和服务器端就完成了一次Web交互。
 
什么是Asp.Net呢?
我喜欢把Asp.Net定义如:
Asp.Net 是一个运行在CLR的托管代码上,从前到后处理Web请求,并响应Web请求的一个AOP框架,它是处理Web请求的一种引擎。它不是仅仅是我们常用的WebForm,WebService,IHttpHandler这些,它还有很多.....
 
 
从浏览器到服务器的过程
我们来看一下,当我们在浏览器地址栏输入http://www.cnblogs.com博客园的网址时,并敲击回车键。这个时候就会从浏览器端生成一个Request请求,并发送给http://www.cnblgos.com的web服务器
,当请求到达web服务器的那一刻,web服务器Windows内核中的HTTP.SYS组件就会捕获到请求。当HTTP.SYS组件分析到这是一个需要交给IIS服务器处理的Http请求时,HTTP.SYS组件就会将Request请求,交给IIS服务器来处理。IIS服务器分析Request请求的context-type类型,然后从处理程序映射表中去匹配,当在处理程序映射表中能够匹配到Request请求的context-type类型时,那么IIS服务器就将请求交给映射表中所对应的程序处理。
图一 : IIS中 处理程序映射表
当IIS发现,在处理程序映射表中没有能匹配的项的时候(当没有匹配项的时候,一般情况下是请求"静态文件"),就直接去下载Request请求所对应路径的文件。如.jpg,html,xml.css文件等等。
图二 : 从浏览器到达服务器的过程
 
回到之前,当服务器在处理如aspx.ashx,等等动态文件的时候,IIS服务器将Request请求,交
给aspnet_isapi.dll文件来处理。
 
ISAPI是第一个也是性能最高Request请求报文最原始的Web请求切入点

aspnet_isapi.dll是一个非常底层,并且是非托管的win32API,这个dll非常简单,非常高效,并且还被微软优化过性能。它用来处理最底层的 指令以及函数回调,并为高层程序提供了应用程序级别服务的功能和接口。

当aspnet_isapi.dll接收到Request请求的时候,aspnet_isapi.dll就会去调动Web服务器中的.Net Framework,最终加载CLR运行环境,并创建一个ISAPIRuntime对象,然后调用ISAPIRuntime对象的ProcessRequest()方法。
ISAPIRuntme.ProcessRequest()方法是进入ASP.Net的第一个入口
ISAPIRuntime.ProcessRequest()方法调用之后主要做了一件事情,就是将Request的原始请求信息封装成HttpWorkRequest类,由于HttpWorkRequest类封装的请求报文很原始,很复杂,所以微软没有将其公开出来。接着执行StartProcessing()方法,来创建HttpRuntime对象并调用其静态方法ProcessRequest()。
图三 : 如何开始ASP.Net
HttRuntime,HttpContext,HttpApplication ?
 
在HttpRuntime对象调用其静态方法ProcessRequest()之后,我们的Web请求开始慢慢进入应用层级别,why?
ProcessRequest()这个方法做了很多事情,具体可以通过Reflector工具查看,但是大致分为四个部分:
1.为请求创建了一个新的HttpContext实例(这个对象就是我们常用的HttpContext上下文对象),并将HttpWorkRequest中最原始的请求
报文封装到HttpContext对象的HttpRequest对象中。
2.通过HttpApplicationFactory(应用程序工厂)得到一个具体的HttpApplication 实例。
3.调用HttpApplication.Init()方法来建立事件请求管道。
4.Init()方法触发了HttpApplication.ResumeProcessing()方法来开始执行Asp.Net事件请求管道。
图四 : HttpRuntime,HttpApplication和HttpContext的关系
Asp.Net事件请求管道详解
 
前面说Asp.Net是一个Aop框架,而Asp.Net事件请求管道就是一点。
Asp.Net事件请求管道,是微软帮程序员提供来处理Web请求的一些列事件,这些事件是依次执行,我们可以通过在这些事件上注册或移除我们自己写的方法,来修改Web请求执行的逻辑。
 
图五 : ASP.Net事件请求管道
 
在第八个事件的时候,会创建请求的页面对象,并转换为IHttpHandler接口。
 
在第九个事件到第十一个事件之间,会接收到浏览器发过来的SessionId。并先会将IHttpHandler接口尝试转换为IRequiresSessionState接口,如果转换成功,Asp.Net会根据这个SessionId到服务器的Session池中去查找所对应的Session对象,并将这个Session对象赋值到HttpContext对象的Session属性。如果尝试转换为IRequiresSessionState接口不成功,则不加载Session。
 
在第十一个事件到第十二个事件之间,会调用在第八个事件创建的页面对象的ProcessRequest方法。
当我们直接使用*.ashx页面的时候,就直接调用了一个FrameworkInitialize(),并最终生成响应报文,发送回客户端。
当我们在使用*.aspx页面的时候,它继承自Page类,而Page类实现了IHttpHandler接口。
由于Page类实现了IHttpHandler接口,在ProcessRequest方法中,调用了FrameworkInitialize()方法。
在FrameworkInitialize()这个方法内部就开始打造Asp.Net的页面控件树(打造html树),在其中就调用了ProcessRequestMain方法,在这个方法里面就执行了整个Asp.Net页面生命周期。
 
IHttpModules
请求通过事件管道,一些列的事件被触发了,我们可以通过在Global.asax全局配置文件中看到这些事件。
但是由于这是由程序分配的事件,可能就不是我们想要的。如果我们想要创建一个能够复用的HttpApplication事件管道来处理Web请求,
我们又想将这些代码复用,或者开发成插件的形式。那么我们就可以使用IHttpModules。
IHttpModules配置很简单,我们只需要在Web.config里面配置一下就可以了。而具体的HttpModules只需要实现IHttpModules接口,并注册自己的方法就行了。
 
<?xml version="1.0"?>
 

<configuration>

    <system.web>
        <httpModules>
            <add name="cnblogsHttpModules" type="cnblogs.cnblogsHttpModules"/>
        </httpModules>
    </system.web>
</configuration>
 
Web.config文件的配置
 
 
publicclass cnblogsHttpModules : IHttpModule
{
    public void MyBeginRequest(object sender, EventArgs e)
    {
        HttpApplication application = sender as HttpApplication;
        application.Context.Response.Write("这个IHttpModule具体类的写法哟!");
    }
}
 
具体的HttpModules类写法
 
Asp.Net页面生命周期详解
Asp.Net是一个Aop框架,而Asp.Net事件请求管道体现了Aop思想,而现在我们要说的Asp.Net页面生命周期也体现Aop思想。
Asp.Net页面生命周期的本质就是微软提供给我们程序员修改页面控件树代码的一些列事件,我们可以通过实现页面生命周期的事件方法来修改控件树代码。
图六 : ASP.Net页面生命周期
 
当ASP.Net执行完我们注册的生命周期事件方法的时候,最后会调用Render方法,Render方法要求传入一个TextWriter文本写出器对象,并遍历所有控件树,调用每个控件的Render方法。
所以每一个控件调用Render方法之后产生的Html字符串都依次写入到TextWriter对象。最后ASP.Net将TextWriter中的Html字符串封装成响应报文,然后发送回客户端。
 
 
结束语
在这里,我介绍了一下ASP.Net的整个处理请求的过程。但有很多底层的信息,我还没有仔细去观察过,因此很多细节可能还是没有注意到。这篇文章可能还是有很多错误的地方,希望博客园的兄弟姐妹们纠错,谢谢。

(转)Asp.Net 请求处理机制的更多相关文章

  1. ASP.Net请求处理机制初步探索之旅 - Part 1 前奏

    开篇:ASP.Net是一项动态网页开发技术,在历史发展的长河中WebForm曾一时成为了ASP.Net的代名词,而ASP.Net MVC的出现让这项技术更加唤发朝气.但是,不管是ASP.Net Web ...

  2. ASP.Net请求处理机制初步探索之旅 - Part 2 核心

    开篇:上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程,这篇我们开始探索ASP.Net的核心处理部分,借助强大的反编译工具,我们会看到几个熟悉又陌生的名词(类):Ht ...

  3. ASP.Net请求处理机制初步探索之旅 - Part 3 管道

    开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest().HttpRuntime.ProcessReq ...

  4. ASP.Net请求处理机制初步探索之旅 - Part 3 管道(转)

    开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest().HttpRuntime.ProcessReq ...

  5. ASP.Net请求处理机制初步探索之旅 - Part 2 核心(转)

    开篇:上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程,这篇我们开始探索ASP.Net的核心处理部分,借助强大的反编译工具,我们会看到几个熟悉又陌生的名词(类):Ht ...

  6. 【转载】ASP.Net请求处理机制初步探索之旅 - Part 3 管道

    开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest().HttpRuntime.ProcessReq ...

  7. ASP.Net请求处理机制初步探索之旅 - Part 1 前奏(转)

        在读本文之前建议先阅读IIS架构:http://www.cnblogs.com/tiantianle/p/5079932.html     不管是ASP.Net WebForm还是ASP.Ne ...

  8. ASP.Net请求处理机制初步探索之旅 - Part 4 WebForm页面生命周期

    开篇:上一篇我们了解了所谓的请求处理管道,在众多的事件中微软开放了19个重要的事件给我们,我们可以注入一些自定义的业务逻辑实现应用的个性化设计.本篇,我们来看看WebForm模式下的页面生命周期. ( ...

  9. ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

    好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: --> 开篇:上一篇 ...

随机推荐

  1. 【转】android-support-v7-appcompat.jar 的安装及相关问题解决 --- 汇总整理

    原文网址:http://tdppro.blog.51cto.com/749956/1388853 1.DownLoading the Support Libraries 1)Start the And ...

  2. Using Nini .NET Configuration Library

    Using Nini .NET Configuration Library Tweet When developing a desktop application, there will be tim ...

  3. HDOJ --- 2577

    How to Type Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...

  4. 51单片机产生1Hz-5kHz可调占空比方波

    学校的课程设计,总结一下. 注意 1.高低电平的改变不适合在主函数的while循环中,因为要有数码管动态显示的延时和其它逻辑处理,时间太长会不能及时改变高低电平值. 2.中断的执行时间一定是不能超过定 ...

  5. 长沙Uber优步司机奖励政策(2月1日~2月7日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. pci转并口卡的安装使用

    pci转并口卡模拟出来的并口并不能完全等同于主板上真正的并口.真正的并口打印的时候可以“直接瓶口输出”打印,而不需要安装打印驱动程序. 这个模拟出来的并口却不能使用“直接瓶口输出”(打印机不打印,程序 ...

  7. JAVA 调用Axis2 code generator 生成的webservice

    以下代码为调用 JAVA 调用Axis2 code generator 生成的webservice的代码. package test; import java.rmi.RemoteException; ...

  8. 色情不是我的所有——在法律边缘起舞的 FC2

    [核心提示] 世界上最大的色情站点之中的一个这项「殊荣」只是是 FC2 无心插柳被用户戴上的一顶帽子,这个从 1999 年成立至今已经超过 15 年历史的互联网活化石,远比你想象中更加高深莫測. 一个 ...

  9. System.currentTimeMillis();

    1.  意义: currentTimeMillis()返回以毫秒为单位的当前时间,返回的是当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位測量).注意,当返回值的时间单 ...

  10. C的printf与scanf的用法

    之前没学过C语言,只学过C++,所以就来自学下C语言了,其实个人认为C与C++的区别很小,基本上就是printf与scanf这点输出和输入的区别了,如果还有什么区别的话那就是要包含的头文件是不同的.比 ...