前言
我们都知道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的原始请求信息封装成ISAPIWorkerRequest类,由于ISAPIWorkerRequest类封装的请求报文很原始,很复杂,所以微软没有将其公开出来。接着执行StartProcessing()方法,来创建HttpRuntime对象并调用其静态方法ProcessRequest()。

图三 : 如何开始ASP.Net

HttRuntime,HttpContext,HttpApplication ?
 
在HttpRuntime对象调用其静态方法ProcessRequest()之后,我们的Web请求开始慢慢进入应用层级别,why?
ProcessRequest()这个方法做了很多事情,具体可以通过Reflector工具查看,但是大致分为四个部分:
1.为请求创建了一个新的HttpContext实例(这个对象就是我们常用的HttpContext上下文对象),并将ISAPIWorkerRequest中最原始的请求
报文封装到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请求执行的逻辑。【第9个请求管道事件为acquirerequeststate】

图五 : 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页面生命周期的本质就是微软提供给我们程序员修改页面控件树代码的一些列事件,我们可以通过实现页面生命周期的事件方法来修改控件树代码。
具体的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字符串封装成响应报文,然后发送回客户端。

来源:http://www.cnblogs.com/cilence/archive/2012/05/28/2520712.html

http://www.360doc.com/content/14/0619/09/10504424_387971542.shtml

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 请求处理机制

    原文:http://www.cnblogs.com/cilence/archive/2012/05/28/2520712.html Asp.Net 请求处理机制   前言 我们都知道Web请求响应是基 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Exception Handling in ASP.NET Web API

    public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErr ...

  2. 从头开始-02.C语言基础

    变量的内存分析: #include <stdio.h> int main() { //内存地址由大到小 int a=10; int b=20; //&是一个地址运算符,取得变量的地 ...

  3. iOS计算文本高度

    NSDictionary *attribute = @{NSFontAttributeName: UIFont(14)}; CGRect labelRect = [string boundingRec ...

  4. poj3090--欧拉函数

    #include<iostream> using namespace std; //欧拉函数 int eular(int n){ ,i; ;i*i<=n;i++){ ){ n/=i; ...

  5. C++ 虚函数机制学习

    致谢 本文是基于对<Inside the c++ object model>的阅读和gdb的使用而完成的.在此感谢Lippman对cfront中对象模型的解析,这些解析帮助读者拨开迷雾.此 ...

  6. [转]前端CSS规范整理

    一.文件规范 1.文件均归档至约定的目录中. 具体要求通过豆瓣的CSS规范进行讲解: 所有的CSS分为两大类:通用类和业务类.通用的CSS文件,放在如下目录中: 基本样式库 /css/core  通用 ...

  7. The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, SettingFragment, String)

    The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the ...

  8. Oracle当前用户SQL

    select sesion.sid,sesion.serial#,sesion.username,sesion.sql_id,sesion.sql_child_number,optimizer_mod ...

  9. SelectDirectory使用方法以及EnableTaskWindows

    SelectDirectory使用方法 格式 Delphi syntax: On Windows: function SelectDirectory(const Caption: string; co ...

  10. [LeetCode][Python]Tow Sum

    # -*- coding: utf8 -*-'''https://oj.leetcode.com/problems/two-sum/ Given an array of integers, find ...