Asp.Net 请求处理机制

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

前言

我们都知道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的整个处理请求的过程。但有很多底层的信息,我还没有仔细去观察过,因此很多细节可能还是没有注意到。这篇文章可能还是有很多错误的地方,希望博客园的兄弟姐妹们纠错,谢谢。

时间: 01-10

Asp.Net 请求处理机制的相关文章

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

开篇:上一篇我们了解了一个ASP.Net页面请求的核心处理入口,它经历了三个重要的入口,分别是:ISAPIRuntime.ProcessRequest().HttpRuntime.ProcessRequest()以及HttpApplication.Init().其中,在HttpApplication的Init()方法中触发了请求处理管道事件的执行,本篇我们就来看看所谓的请求处理管道. (1)Part 1:前奏 (2)Part 2:核心 (3)Part 3:管道 (4)Part 4:WebForm

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

开篇:ASP.Net是一项动态网页开发技术,在历史发展的长河中WebForm曾一时成为了ASP.Net的代名词,而ASP.Net MVC的出现让这项技术更加唤发朝气.但是,不管是ASP.Net WebForm还是ASP.Net MVC在请求处理机制上大部分都是相同的,只是在请求处理管道上的处理事件做了不同的操作,因此,本文标题不区分ASP.Net WebForm和ASP.Net MVC,但在后续的介绍中会区分开来介绍. (1)Part 1:前奏 (2)Part 2:核心 (3)Part 3:管道

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

   不管是ASP.Net WebForm还是ASP.Net MVC在请求处理机制上大部分都是相同的,只是在请求处理管道上的处理事件做了不同的操作.因此,本文标题不区分ASP.Net WebForm和ASP.Net MVC,但在后续的介绍中会区分开来介绍.此外,本文以IIS经典模式为主,不讨论集成模式(IIS7后加入了集成模式,不用加载外部的aspnet_isapi.dll组件). 一.当一个请求到来时HTTP.sys先进行了基本处理,然后转发给IIS的工作者进程. 主要看工作者进程做了什么.

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

  上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程,这篇我们开始探索ASP.Net的核心处理部分,借助强大的反编译工具,我们会看到几个熟悉又陌生的名词(类):HttpWorkerRequest.HttpRuntime.HttpContext.HttpApplication等. 一.第一个入口:ISAPIRuntme.ProcessRequest()    ISAPIRuntime是进入NET托管环境的入口,在其PR方法中通过一个ecb句柄指向了当前请求报文体的

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

好听的歌 我一直觉得看一篇文章再听一首好听的歌,真是种享受.于是,我在这里嵌入一首好听的歌,当然你觉得不想听的话可以点击停止,歌曲 from 王菲 <梦中人>: 开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init.加载Load以及呈现Render三个重要阶段,其中构造了页面控件树,并对页面控件树进行了大量的递归操作,最后将与模板结合生成的HTML返回给了浏览器.那么,在ASP.NET MVC模式下,一个页面的生命周期又经历了哪些步凑呢?别急,本篇漫漫

动态网页的工作机制——Asp.net 运行机制

一.Asp.net 运行机制概述 1.使用Asp.net 进行动态Web开发,编写好Web应用程序,即动态页面,并部署到Web服务器,如IIS中: 2.客户端在浏览器输入地址,请求相应的动态页面: 3.Web 服务器根据客户端的请求,对Web应用程序进行编译或解释,并生成HTML流,返回给客户端 4.客户端浏览器解释HTML流,并显示为Web页面 二.Asp.net 运行机制详解 图1.1 ASP.NET 处理请求的内部过程 1.当请求发送到服务器IIS并被其接受后,IIS服务器会判断请求文件的

ASP.NET 运行机制续(完结)

上一篇说到applicationInstance会执行一些列的事件.下面是我在msdn上找到有关asp.net程序生命周期相关的描述及图片 声明周期的起始 ASP.NET 应用程序的生命周期以浏览器向 Web 服务器(对于 ASP.NET 应用程序,通常为 IIS)发送请求为起点. ASP.NET 是 Web 服务器下的 ISAPI 扩展. Web 服务器接收到请求时,会对所请求的文件的文件扩展名进行检查,确定应由哪个 ISAPI 扩展处理该请求,然后将该请求传递给合适的 ISAPI 扩展. A

ASP.NET 事件驱动机制

关于 ASP.NET Web窗体应用程序,以前在项目中项目中也一直在使用,但直到最近才了解到 Web 窗体应用程序的核心之一事件驱动,做 Web 窗体应用程序的人都在应用这个特性,但是不是每个人都了解这个特性,简而言之,就是每一个Button控件都有一个独立的事件,通过点击不同的 Button 来执行不同的后台事件,进而实现不同的业务流程. 1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind=&

Asp.net底层机制

Asp.net底层就是用户通过输入网址,然后请求IIs服务器的流程,在这个过程中有一个重要的部件就是ISAPI,这是一个底层的win32API,在扩展方面比较困难,多用于接口之间的桥接,.net和IIS通过IISAPI进行交互的,IIS中后缀名.aspx,通过应用程序扩展映射到.net的ISAPI扩展的dll,这个dll就是aspnet_isapi.dll,访问都是通过这个dll中相应的映射完成的. 1.通过asp.net的映射机制使用后缀名从ISAPI中获取到接收的请求,并将请求的路由到相应的