ASP.NET架构简介

来源:互联网 发布:淘宝助理数据包格式 编辑:程序博客网 时间:2024/04/30 19:53

引言:在大多数介绍Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net。他们耐心,细致地告诉你如何一步步拖放控件,设置控件属性,编写后台代码,以现实某个特定的功能。这种做法实际上是回答了"如何去做"的问题,却没有回答"为什么可以这样做"的问题。 当你按"如何去做"所讲解的内容去开发程序的时候,对于你的用户,你仍然是一名程序员,但对于实现Asp.Net框架类的微软程序员来讲,你已经成为了他们的一个客户。希望通过这篇文章的讲解,可以让你熟悉了解Asp.Net底层运作原理。

Note:我不反对"如何去做",这样有它的好处,就是可以快速开发。我只是建议多掌握一点底层知识,这时对一些问题将有更好的理解。

Http请求处理流程概述

思考"为什么在网站地址栏中输入一个正确的Url地址就能呈现相关的页面?",对于普通的访问者来说,这就象太阳东边升起西边落下一样理所当然,但对于程序员来说,认为这个与自己无关,不过是系统管理员或网管的责任。毕竟,IIS是Windows的一个组件,又不是Asp.Net的一个组成部分。而实际上,从你轻拍回车到页面呈现短短的时间内,IIS和.Net Framework已经做了大量的幕后工作。你可能认为了解这些幕后工作如何运作是无关紧要的,作为程序员的你只需要保证开发出的程序能够高效地运行就行了。然而,在开发过程中,却常常发现需要使用诸如HttpContext这样的类。这个时候,你可曾想过这些类的构成和类的实体是如何创建的?你可能简单回答:HttpContext代表当前请求的上下文环境。可你又知道IIS,.Net Framework,Asp.Net是如何协同处理每一个Http请求,如何区分不同的请求,IIS,.Net Framework,Asp.Net三者之间的数据又是如何流动的?

回答上面的问题,就需要首先了解IIS是如何处理页面请求的。这也是理解Form验证模式和Windows验证模式的基础。

当服务器接收到一个Http请求时,IIS首先需要决定如何去处理这个请求(注:服务器处理一个.html页面和.aspx页面肯定是不一样的嘛。)那么IIS根据什么去处理的呢?答案是根据文件的后缀名。服务器获取所请求的页面(当然也可以是文件,如图片文件)的后缀名后,接下来会在服务器端寻找可以处理这类后缀名的应用程序,如果IIS找不到处理此类文件的应用程序,并且这个文件也没有受到服务器端的保护(一个受保护的例子就是App_Code中的文件,一个不受保护的例子就是你的JS脚本),那么IIS将直接把该文件返还给客户端。

能够处理各种后缀名的应用程序,通常被称为ISAPI应用程序(Internet Server Application Programe Interface,互联网服务器应用程序接口)。ISAPI听起来挺气派,也算是"应用程序"呢,但仔细看它的名称你就全明白了:它实际上只是一个接口,起到一个代理的作用,它的主要工作是映射所请求的页面(或文件)和此后缀名相对应的实际处理程序。让我们进一步看看ISAPI,看看它到底是什么样子,请按下面步骤进行:

1.打开IIS;

2.任选一个站点,鼠标右击,点属性;

3.选择"主目录"选项卡,点击"配置",您将看到如下画面:

 

图1.应用程序配置

很清楚地能够看到,所有IIS能够处理,或者叫ISAPI所提供代理服务的文件类型,及其相对应的实际的后台处理程序都在这里清楚地列出来了。我们找到.aspx的应用处理程序,然后点"编辑",就会出现如下画面:

图2.编辑.aspx应用程序配置

到这里,可以看出,所有的.aspx文件实际上都是由aspnet_isapi.dll这个程序来处理的,当IIS把对于.aspx页面的请求提交给aspnet_isapi.dll以后,IIS就不再关心这个请求随后是怎样处理的了。

理解宿主环境(Hosting)

从本质上讲,Asp. Net主要是由一系列的类组成的。这些类的主要目的就是将Http请求转变为对客户端的响应。HttpRuntime是Asp.Net的一个主要入口类,它有一个称作ProcessRequest的方法,这个方法以一个HttpWorkerRequest类作为参数。HttpRuntime类几乎包含了关于单个Http请求的所有信息:所请求的文件,服务器端变量,QueryString,Http头信息等。Asp.Net使用这些信息来加载,运行正确的文件,并且将这个请求转换到输出流中,一般来说,就是一个Html页面。

当web.config文件内容发生改变,或者.aspx文件发生变动时,为了能够卸载运行在同一进程中的应用程序,Http请求被分别放在相互隔离的应用程序域中。(可自己查阅应用程序域相关知识)。

对于IIS来说,它依赖一个叫做HTTP.SYS的内置驱动程序来监听来自外部的Http请求。在操作系统启动的时候,IIS首先会在HTTP.SYS中注册自己的虚拟路径,这个过程实际上就是告诉HTTP.SYS哪些Url是可以访问的,哪些是不可以访问的。举个例子说明,为什么你访问一个不存在的文件会出现404错误呢?就是在这一步确定的。如果请求一个可以访问的Url,HTTP.SYS将会将这个请求转交给IIS工作者进程(在IIS6.0中,该进程叫做w3wp.exe,在IIS5.0中,该进程叫做aspnet_wp.exe)。接下来进行的事情就是讲述前面所讲的ISAPI了。

除了映射文件与其对应的应用处理程序外,ISAPI还做了一些其他的工作:

1.从HTTP.SYS中获取当前的Http请求信息,并将这些信息保存到HttpWorkerRequest类中;

2.在相互隔离的应用程序域中加载HttpRuntime;

3.调用HttpRuntime的ProcessRequest方法。
接下来才是程序员通常编写的代码所完成的工作了,然后IIS接收返回的数据流,并重新返还给HTTP.SYS,最后由HTTP.SYS再将这些数据返还给客户端浏览器。

图3.Asp.Net宿主环境

理解管道

在前面的介绍中,我们是在一个比较低的层次上讨论了从发出Http请求到看到浏览器输出这瞬间的短短时间内IIS,.Net Framework所做的事情。但是我们忽略了一个细节,那就是程序员编写的代码是如何在这一过程中衔接的。下面我们来看看这个问题。

当Http请求进入到HttpRuntime后,它的管道有托管模块(Module)和处理器(Handler)组成,并且由管道来处理这个Http请求。

图4.Http请求管道

我们按编号来看下这幅图中的数据是如何流动的。

1.HttpRuntime将Http请求转交给HttpApplication,HttpApplication代表着程序员创建的Web应用程序。HttpApplication创建针对此请求的HttpCntext对象,这些对象包含了关于此请求的诸多其他对象,主要是HttpRequest,HttpResponse,HttpSessionState等。这些对象可以通过Page类或者Context类进行访问。

2.接下来Http请求通过一些Module,这些Module可以做一些执行某个实际工作前的一些事情。

3.在这一步中,执行实际的一些操作,通常也就是.aspx页面所完成的业务逻辑。

4.Http请求再一次返回到Module,此时Module可以做一些某个工作已经完成了之后的事情。

 

原创粉丝点击