ASP.NET框架

一、框架概述

 

为了服务于一个default.aspx的网页请求,ASP.NET运行库需要获得对Asp.default_aspx类的引用。如果AppDomain当前加载的任何一个程序集中都没有该类,就创建该类。接着,HTTP运行时环境通过接口IHttpHandler调用该类中的ProcessRequest方法。大致包括如下三方面:

 

1、输入请求的转换

每个引用.aspx资源的输入请求都会被映射到Page的派生类。ASP.NET HTTP运行时首先会确定处理该请求的类名。页面的URL与类名会通过某种命名约定关联在一起。例如,若请求的页面为default.aspx,则可推断出相关联的类名为ASP.default_aspx。如果当前加载到AppDomain的程序集中不包含带有这个名称的类,HTTP运行库将会发出该类的创建和编译命令。使该页面转化为程序集,保存在ASP.NET临时文件夹中。当同一页面的请求再次到达时,由于该类已经存在,所以不会再执行编译过程。

 

2、.aspx页面转化为程序集

在Web应用程序上下文中,.aspx页面会在第一次被请求时,按需被动态编译为程序集。

特定.aspx资源程序集的生成,分为两个步骤进行。首先,该.aspx资源文件的源代码会被解析为直接或间接派生于Page类的相应的类,然后,动态生成的类会被编译为程序集,该程序集缓存到ASP.NET专用的临时目录下。

只要.aspx源文件没有被更改,且整个应用程序没有重启,已编译的页面就一直存在,以下情况将导致所有页面的重新编译:

l  对.aspx文件的任何修改,将使相关程序集变为无效,并在该页面下一次被请求时,强制HTTP运行库创建新的程序集。

l  编辑web.config或者global.asax之类的文件会导致整个应用程序重启。在这种情况下,在某个页面被请求时,所有页面会被重新编译。

l  如果Bin文件夹中的程序集被改动(新建或被替换),所有页面也会被重新编译。

 

3、Page类实现IHttpHandler接口

根类Page实现了IHttpHandler接口,它包含两个成员,ProcessRequest方法和IsReusable属性。一旦HTTP运行库获得代表该请求的页面的类的实例,便会调用ProcessRequest公共方法开始进行处理,以便向浏览器做出响应后终结。调用并执行ProcessRequest及其所触发事件的整个过程统称为“页面的生命周期”。

整个ASP.NET的框架大概分为三个部分:IIS、HTTP运行时和页面:

 

二、IIS

 

IIS对Web服务器的所有资源按扩展名进行组织。当某个资源的请求到达时,IIS首先会判断所请求的资源类型,对于静态资源(如图像、文本文件、HTML页面和非脚本ASP页面)直接由IIS处理;对于需要在服务器端处理的请求,会被分配给特定的运行时进程模块进行实际的处理。

IIS中能够处理Web资源的模块是ISAPI扩展,ISAPI扩展是一些Win32动态链接库,当IIS需要ISAPI扩展完成某项任务时,它会加载相应的DLL,并通过有效参数调用适当的函数。例如,.asp页面会由名为asp.dll的ISAPI扩展处理,.aspx页面会由名为aspnet_isapi.dll的ISAPI扩展处理。

IIS6.0管道以一种名为w3wp.exe的工作进程为中心,该可执行程序的副本由分配给同一应用程序池的所有Web应用程序共享。w3wp.exe工作进程会加载aspnet_isapi.dll,随后,ISAPI扩展加载CLR,启动ASP.NET运行时管道,对请求进行处理。如图:

 

IIS6.0以内核级模块的形式实现了其HTTP监听程序。所有的输入请求会首先被一个驱动程序(http.sys)管理,http.sys驱动程序会监听请求,并将其追加到相应的应用程序池请求队列中。一个叫“Web管理服务”(WAS)的模块会读取IIS元库,并指示http.sys创建请求队列,队列数量与元库中注册的应用程序池的数量一致。

 

三、HTTP运行时

 

HTTP运行时处理请求的管线如图:

 

 

1、HttpRuntime对象

网页请求会传递给HTTP运行时管道中的每一个处理原始HTTP有效负载的对象,HttpRuntime就是该管道的入口点。ASP.NET工作进程创建HttpRuntime类的实例,并调用其ProcessRequest方法来激活该HTTP管道。

HttpRuntime对象会在创建时对许多辅助处理页面请求的内部对象进行初始化,这些辅助对象包括缓存管理器和文件系统监视器。ProcessRequest方法被调用后,它还会创建新的上下文对象(HttpContext类的实例),它封装了所有与该请求有关的HTTP的特有的信息,之后,HttpRuntime对象使用上下文对象通过HttpApplicationFactory对象创建HttpApplication对象,并调用HttpApplication的异步方法BeginProcessRequest。

 

2、HttpApplicationFactory对象

HttpApplicationFactory对象维护着许多HttpApplication对象,当该程序工厂对象被调用后,如果对象池中有可用的对象,则返回可用的HttpApplication对象,如果没有可用的,则创建一个新的HttpApplication对象返回。

 

3、HttpAplication对象

HttpApplication对象用于处理页面请求,每次处理一个(多个对象用于处理并发请求)。

HttpApplication或其派生类(如果有global.asax)的实例负责管理分配给它的请求的整个生命周期。只有在该请求处理完毕后,该实例才会被重用。HttpApplication维护着一系列HTTP模块对象。这些对象可以对请求的内容进行筛选,甚至可以进行修改。

HttpApplication对象能判断代表请求资源的对象类型(ASP.NET页面,Web服务或用户控件)。随后,HttpApplication使用相应的处理程序工厂获取代表该请求资源的对象。处理程序工厂是实现IHttpHandlerFactory类的实例,负责返回处理HTTP请求的托管对象(对于ASP.NET页面则是一个Page类对象)。

 

4、IHttpHandlerFactory接口

一旦HttpApplication对象掌管了请求,就必须选择一个合适的处理程序,并创建该处理程序的实例。对于面向页面的请求,对应的工厂名为PageHandlerFactory。对于其它如Web服务,用户控件则选择其它实现IHttpHandlerFactory接口的处理程序。

接到请求时,页面处理工厂会创建代表被请求页面的对象实例。页面对象随后被传回HttpRuntime对象。最后的步骤由ASP.NET运行库完成,ASP.NET运行库会调用IHttpHandler的页面对象的ProcessRequest方法。这会使页面执行用户定义的代码,并为浏览器生成标记。

 

四、页面

 

每次客户端请求都会创建页面实例,它的执行使自身及其包含的控件经历页面生命周期的各个阶段。页面的执行起始于HTTP运行库调用ProcessRequest时,该方法将启动页面并控制它的生命周期。生命周期由一系列阶段和步骤组成,一些阶段可以通过用户编码的事件进行控制,而一些需要对方法进行重写。其他阶段没有被公开,因此开发者无法控制。

页面的生命周期可以分为三个阶段:建立阶段、回发阶段和终结阶段。每个阶段会有子阶段,分别由若干步骤和事件引发点组成。

 

1、页面的建立

页面生命周期的第一个阶段是确定运行库处理当前页面请求的原因。这个原因有很多种:常规请求、回发、跨页投递或回调。基于实际的原因,页面对象会配置其内部状态,如果包含被投递的值,还会根据请求的方法(GET或POST)准备该值的集合。这一阶段包含有如下子阶段。

1)页面初始化

这一阶段主要包含有PreInit、Init、InitComplete事件过程。

2)视图状态的恢复

如果页面因回发而被处理(IsPostBack属性为true)。隐含字段_VIEWSTATE的值会被恢复。用于恢复上一次请求时的状态。

3)处理被投递的数据

客户端投递的数据通常使用&分割的键值对,这些值会被加载到一个内部使用的集合当中。页面处理程序会试图寻找被投递集合中的名称与页面中控件ID的匹配项。如果找到匹配项,处理程序会检查该服务器控件是否已实现IPostBackDataHandler接口。如果已实现,页面处理程序会调用该接口的LoadPostData方法。如果它返回true(即状态已被更新),该控件将被添加到一个独立的集合中,等待进一步指示。

4)控件树的创建

            这一阶段主要包括PreLoad、Load事件。

 

2、回发的处理

回发机制的过程为,将窗体数据投递到原页面,构建此次请求过程的上下文。这期间有如下子过程:

1)控件状态变化

对于所有在“处理被投递的数据”中LoadPostData方法返回true的控件,这是会执行IPostBackDataHandler接口的RaisePostDataChangedEvent方法。该方法发出信号给控件,通知ASP.NET应用程序该控件的状态已被更改。该方法的实现取决于具体控件。然而,大多数控件会做这样一件事情:引发服务器事件,为页面的设计者提供一个介入的机会,以便对特定情况做处理。例如,如果TextBox的Text属性在回发间被更改。该TextBox会向宿主页面引发TextChanged事件。

2)服务器端回发事件的执行

页面处理程序会分析被投递的数据,确定引起回发的控件。如果该控件实现了IPostBackEventHandler接口,处理程序会调用该接口的RaisePostBackEvent方法。该方法的实现取决于具体控件,然而,实际上任何主动投递控件都会引起服务器事件,以便页面的设计者能够编写代码对回发做出反应(例如,Button控件会引发OnClick事件)。

 

3、页面的呈现

呈现阶段分为两部分:预呈现和标记生成。预呈现这个子阶段由两个事件表征:预处理和投递处理。

1)预呈现

预处理:通过处理PreRender事件,页面和控件可以进行生成输出前的任何更改。

投递处理:在每个控件被呈现输出,为页面生成标记的前一段时间里,要将当前页面的状态存储在视图状态介质中。

2)标记的生成

每个子控件生成的标记会被存储到一个缓冲中。没有与该阶段项关联的用户事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值