简介
对由 Microsoft? Internet 信息服务 (IIS) 处理的 Microsoft?
ASP.NET 页面的每个请求都会被移交到 ASP.NET HTTP 管道。HTTP 管道由一系列托管对象组成,这些托管对象按顺序处理请求,并将 URL
转换为纯 HTML 文本。HTTP 管道的入口是 HttpRuntime 类。ASP.NET 结构为辅助进程中的每个 AppDomain
创建一个此类的实例。(请注意,辅助进程为每个当前正在运行的 ASP.NET 应用程序维护一个特定的
AppDomain。)
HttpRuntime 类从内部池中获取 HttpApplication 对象,并安排此对象来处理请求。HTTP
应用程序管理器完成的主要任务就是找到将真正处理请求的类。当请求 .aspx 资源时,处理程序就是页面处理程序,即从 Page
继承的类的实例。资源类型和处理程序类型之间的关联关系存储在应用程序的配置文件中。更确切地说,默认的映射集是在 machine.config 文件的
<httpHandlers> 部分定义的。但是,应用程序可以在本地的 web.config 文件中自定义自己的 HTTP 处理程序列表。以下这一行代码就是用来为
.aspx 资源定义 HTTP 处理程序的。
<add verb="*" path="*.aspx"
type="System.Web.UI.PageHandlerFactory"/>
扩展名可以与处理程序类相关联,并且更多是与处理程序工厂类相关联。在所有情况下,负责处理请求的
HttpApplication 对象都会获得一个实现 IHttpHandler 接口的对象。如果根据 HTTP
处理程序来解析关联的资源/类,则返回的类将直接实现接口。如果资源被绑定到处理程序工厂,则还需要额外的步骤。处理程序工厂类实现
IHttpHandlerFactory 接口,此接口的 GetHandler 方法将返回一个基于 IHttpHandler 的对象。
HTTP
运行时是如何结束这个循环并处理页面请求的?ProcessRequest 方法在 IHttpHandler
接口中非常重要。通过对代表被请求页面的对象调用此方法,ASP.NET 结构会启动将生成浏览器输出的进程。
真正的 Page 类
特定页面的 HTTP 处理程序类型取决于 URL。首次调用 URL 时,将构建一个新的类,这个类被动态编译为一个程序集。检查
.aspx 资源的分析进程的结果是类的源代码。该类被定义为命名空间 ASP 的组成部分,并且被赋予了一个模拟原始 URL 的名称。例如,如果 URL 的终点是
page.aspx,则类的名称就是 ASP.Page_aspx。不过,类的名称可以通过编程方式来控制,方法是在 @Page 指令中设置 ClassName
属性。
HTTP 处理程序的基类是 Page。这个类定义了由所有页面处理程序共享的方法和属性的最小集合。Page 类实现
IHttpHandler 接口。
在很多情况下,实际处理程序的基类并不是
Page,而是其他的类。例如,如果使用了代码分离,就会出现这种情况。代码分离是一项开发技术,它可以将页面所需的代码隔离到单独的 C# 和 Microsoft
Visual Basic? .NET 类中。页面的代码是一组事件处理程序和辅助方法,这些处理程序和方法真正决定了页面的行为。可以使用 <script
runat=server> 标记对此代码进行内联定义,或者将其放置在外部类(代码分离类)中。代码分离类是从 Page 继承并使用额外的方法的类,被指定用作
HTTP 处理程序的基类。
还有一种情况,HTTP 处理程序也不是基于 Page 的,即在应用程序配置文件的 <pages> 部分中,包含了
PageBaseType 属性的重新定义。
<pages PageBaseType="Classes.MyPage, mypage"
/>
PageBaseType 属性指明包含页面处理程序的基类的类型和程序集。从 Page
导出的这个类可以自动赋予处理程序扩展的自定义方法和属性集。
页面的生命周期
完全识别 HTTP
页面处理程序类后,ASP.NET 运行时将调用处理程序的 ProcessRequest 方法来处理请求。通常情况下,无需更改此方法的实现,因为它是由 Page
类提供的。
此实现将从调用为页面构建控件树的 FrameworkInitialize 方法开始。FrameworkInitialize 方法是
TemplateControl 类(Page 本身从此类导出)的一个受保护的虚拟成员。所有为 .aspx 资源动态生成的处理程序都将覆盖
FrameworkInitialize。在此方法中,构建了页面的整个控件树。
接下来,ProcessRequest
使页面经历了各个阶段:初始化、加载视图状态信息和回发数据、加载页面的用户代码以及执行回发服务器端事件。之后,页面进入显示模式:收集更新的视图状态,生成 HTML
代码并随后将代码发送到输出控制台。最后,卸载页面,并认为请求处理完毕。
在各个阶段中,页面会触发少数几个事件,这些事件可以由 Web
控件和用户定义的代码截取并进行处理。其中的一些事件是嵌入式控件专用的,因此无法在 .aspx
代码级进行处理。
要处理特定事件的页面应该明确注册一个适合的处理程序。不过,为了向后兼容早期的 Visual Basic
编程风格,ASP.NET
也支持隐式事件挂钩的形式。默认情况下,页面会尝试将特定的方法名称与事件相匹配,如果实现匹配,则认为此方法就是匹配事件的处理程序。ASP.NET
提供了六种方法名称的特定识别,它们是 Page_Init、Page_Load、Page_DataBind、Page_PreRender 和
Page_Unload。这些方法被认为是由 Page 类提供的相应事件的处理程序。HTTP
运行时会自动将这些方法绑定到页面事件,这样,开发人员就不必再编写所需的粘接代码了。例如,如果命名为 Page_Load 的方法绑定到页面的 Load
事件,则可省去以下代码。
this.Load += new
EventHandler(this.Page_Load);
对特定名称的自动识别是由 @Page 指令的 AutoEventWireup
属性控制的。如果该属性设置为
false,则要处理事件的所有应用程序都需要明确连接到页面事件。不使用自动绑定事件的页面性能会稍好一些,因为不需要额外匹配名称与事件。请注意,所有
Microsoft Visual Studio? .NET 项目都是在禁用 AutoEventWireup 属性的情况下创建的。但是,该属性的默认设置是
true,即 Page_Load
等方法会被识别,并被绑定到相关联的事件。
下表中按顺序列出了页面的执行包括的几个阶段,执行的标志是一些应用程序级的事件和/或受保护并可覆盖的方法。
表
1:ASP.NET 页面生命中的关键事件
阶段 |
页面事件 |
可覆盖的方法 |
页面初始化 |
Init |
|
加载视图状态 |
|
LoadViewState |
处理回发数据 |
|
任意实现 IPostBackDataHandler 接口的控件中的 LoadPostData 方法 |
加载页面 |
Load |
|
回发更改通知 |
|
任意实现IPostBackDataHandler接口的控件中的RaisePostDataChangedEvent 方法
|
处理回发事件 |
由控件定义的任意回发事件 |
任意实现 IPostBackDataHandler 接口的控件中的 RaisePostBackEvent
方法 |
页面显示前阶段 |
PreRender |
|
保存视图状态 |
|
SaveViewState |
显示页面 |
|
Render |
卸载页面 |
Unload |
|
以上所列的阶段中有些在页面级是不可见的,并且仅对服务器控件的编写者和要创建从
Page
导出的类的开发人员有意义。Init、Load、PreRender、Unload,再加上由嵌入式控件定义的所有回发事件,就构成了向外发送页面的各个阶段标记。
执行的各个阶段
页面生命周期中的第一个阶段是初始化。这个阶段的标志是 Init
事件。在成功创建页面的控件树后,将对应用程序触发此事件。换句话说,当 Init 事件发生时,.aspx
源文件中静态声明的所有控件都已实例化并采用各自的默认值。控件可以截取 Init 事件以初始化在传入的 Web
请求的生命周期内所需的所有设置。例如,这时控件可以加载外部模板文件或设置事件的处理程序。请注意,这时视图状态信息尚不可用。
初始化之后,页面框架将加载页面的视图状态。视图状态是名称/值对的集合,在此集合中,控件和页面本身存储了对所有
Web
请求都必须始终有效的全部信息。视图状态代表了页面的调用上下文。通常,它包含上次在服务器上处理页面时控件的状态。首次在会话中请求页面时,视图状态为空。默认情况下,视图状态存储在静默添加到页面的隐藏字段中,该字段的名称是
__VIEWSTATE。通过覆盖 LoadViewState 方法(Control
类的受保护、可覆盖方法),组件开发人员可以控制视图状态的存储方式以及视图状态的内容映射到内部状态的方式。
有些方法(如
LoadPageStateFromPersistenceMedium 以及其对应的
SavePageStateToPersistenceMedium),可以用来将视图状态加载并保存到其他存储介质(例如会话、数据库或服务器端文件)中。与
LoadViewState 不同,上述方法只能在从 Page
导出的类中使用。
存储视图状态之后,页面树中控件的状态与页面最后一次显示在浏览器中的状态相同。下一步是更新它们的状态以加入客户端的更改。处理回发数据阶段使控件有机会更新其状态,从而准确反映客户端相应的
HTML 元素的状态。例如,服务器的 TextBox 控件对应的 HTML 元素是 <input type=text>。在回发数据阶段,TextBox
控件将检索 <input> 标记的当前值,并使用该值来刷新自己内部的状态。每个控件都要从回发的数据中提取值并更新自己的部分属性。TextBox 控件将更新它的
Text 属性,而 CheckBox 控件将刷新它的 Checked 属性。服务器控件和 HTML 元素的对应关系可以通过二者的 ID
找到。
在处理回发数据阶段的最后,页面中的所有控件的状态都将使用客户端输入的更改来更新前一状态。这时,将对页面触发 Load
事件。
页面中可能会有一些控件,当其某个敏感属性在两个不同的请求中被修改时,需要完成特定的任务。例如,如果 TextBox
控件的文本在客户端被修改,则此控件将触发 TextChanged
事件。每个控件在其一个或多个属性被修改为客户端输入的值时都可以决定触发相应的事件。对于这些更改对其非常关键的控件,控件实现
IPostBackDataHandler 接口,此接口的 LoadPostData 方法是在 Load 事件后立即调用的。通过对 LoadPostData
方法进行编码,控件将验证自上次请求后是否发生了关键更改,并触发自己的更改事件。
页面生命周期中的关键事件是被调用以执行服务器端代码的事件,此代码与客户端触发的事件相关联。当用户单击按钮时,将回发页面。回发值的集合中包括启动整个操作的按钮的
ID。如果控件实现 IPostBackEventHandler 接口(如按钮和链接按钮),页面框架将调用 RaisePostBackEvent
方法。此方法的行为取决于控件的类型。就按钮和链接按钮而言,此方法将查找 Click
事件处理程序并运行相关的委托。
处理完回发事件之后,页面就可以显示了。这个阶段的标志是 PreRender
事件。控件可以利用这段时间来执行那些需要在保存视图状态和显示输出的前一刻执行的更新操作。下一个状态是
SaveViewState,在此状态中,所有控件和页面本身都将更新自己 ViewState 集合的内容。然后,将得到序列化、散列、Base64
编码的视图状态,而且此视图状态与隐藏字段 __VIEWSTATE 相关联。
通过覆盖 Render 方法可以改变各个控件的显示机制。此方法接受
HTML 书写器对象,并使用此对象来积累所有要为控件生成的 HTML 文本。Page 类的 Render
方法的默认实现包括对所有成员控件的递归调用。对于每个控件,页面都将调用 Render 方法,并缓存 HTML
输出。
页面生命中的最后一个标志是 Unload
事件,在页面对象消除之前发生。在此事件中,您应该释放所有可能占用的关键资源(例如文件、图形对象、数据库连接等)。
在此事件之后,也就是最后,浏览器接收
HTTP 响应数据包并显示页面。
小结
ASP.NET 页面对象模型因其事件机制而显得格外新颖独特。Web
页面由控件组成,这些控件既可以产生丰富的基于 HTML 的用户界面,又可以通过事件与用户交互。以前,在 Web
应用程序的上下文中设置事件模型是件有挑战性的工作。可我们惊奇的看到,客户端生成的事件可以由服务器端的代码来解决,而且只进行一些相应的修改后,此过程仍可以输出相同的
HTML 页面。
掌握这个模型对于了解页面生命周期的各个阶段,以及页面对象如何被 HTTP 运行时实例化并使用是非常重要的。
分享到:
相关推荐
页面生命周期是ASP.NET页面对象模型的核心概念,包括一系列事件,如初始化、加载、回发数据、验证、呈现和卸载。这些事件提供了开发者介入和控制页面行为的机会。例如,`Page_Load`事件用于在页面加载时执行特定...
ASP.NET页面对象模型是微软开发的ASP.NET框架中的核心概念,用于处理Web应用程序中的用户交互、数据处理和页面生命周期管理。这一模型为开发者提供了一种结构化的编程方式,使得创建动态网页变得更加高效和灵活。 ...
总结来说,ASP.NET页面对象模型提供了一个强大且灵活的框架,用于构建动态Web应用。通过理解页面生命周期、事件模型和Page类的功能,开发者可以有效地控制和扩展ASP.NET页面的行为,以满足各种复杂的应用场景。无论...
1. **HttpApplication对象**:它是所有请求进入Asp.Net应用程序的入口点,是ASP.NET管道模型的核心。它负责管理请求的生命周期,执行事件,并协调其他内置对象的工作。 2. **HttpContext对象**:它包含了关于当前...
ASP.NET页面执行模型和服务器控件生存周期模型是ASP.NET框架的核心组成部分,它们定义了如何处理客户端请求,以及服务器控件如何在Web应用程序中创建、初始化、处理事件和销毁。理解这两个模型对于开发高效且可靠的...
ASP.NET页面中包含两种代码模型,一种是单文件页模型,另一种是代码隐藏页模型。这两个模型的功能完全一样,都支持控件的拖拽,以及智能的代码生成。 4.1.2 单文件页模型 单文件页模型中的所有代码,包括控件代码、...
6. **页面生命周期**:讲解ASP.NET页面从请求到响应的生命周期,以及在此过程中组件如何参与和响应。 7. **部署和复用**:介绍如何将组件打包成DLL或Assembly,以便在不同项目中复用,以及在IIS上的部署策略。 8. ...
- HttpHandler(或IHttpHandler)是实际处理HTTP请求的对象,它可以是ASP.NET页面、Web服务或其他自定义的处理程序。HttpHandler接收HTTP请求,生成响应内容,并通过HttpWriter返回给客户端。 - ...
ASP.NET页面经历一系列处理步骤,从开始到结束,包括以下几个关键阶段: 1. **页请求**:在生命周期开始前,ASP.NET判断是否需要分析和编译页面,或者可以直接从缓存中提供响应。 2. **开始阶段**:设置页属性如...
此外,HttpApplication 对象是 ASP.NET 管道模型中的主要组件,它协调一系列 HttpModule 和 HttpHandler 来处理请求。 HttpModule 是 ASP.NET 管道中的可插拔组件,它们可以拦截请求,执行预处理或后处理操作。例如...
1. **ASP.NET页面生命周期**:了解ASP.NET页面从请求到响应的生命周期是非常重要的。这包括初始化、加载、验证、呈现和卸载等阶段,理解这些阶段有助于优化性能并处理用户输入。 2. **C#编程**:作为.NET框架的主要...
在IT领域,面向对象编程(Object-Oriented Programming,OOP)是一种常见的编程范式,尤其是在Web应用开发中,如ASP.NET。ASP.NET是微软公司推出的一种用于构建动态网站、Web应用程序和Web服务的框架,它支持多种...
1. **Page对象**:每个ASP.NET页面都是一个Page类的实例,它是所有网页交互的基础。Page对象提供了处理生命周期事件、访问控件以及与服务器端代码交互的能力。学习如何在Page生命周期的不同阶段中进行操作,如初始化...
1. **控件模型**:ASP.NET 2.0提供了丰富的服务器控件,如Button、Label、TextBox等,这些控件极大地简化了用户界面的开发。控件还支持数据绑定,可以直接与数据库交互,展示和编辑数据。 2. **母版页(Master Pages...
1. **ASP.NET架构**:介绍ASP.NET的工作原理,包括页面生命周期、请求响应流程和组件模型。 2. **Web Forms**:这是ASP.NET的早期模型,通过控件和事件驱动的方式构建页面。学习如何使用各种服务器控件,如文本框、...
ASP.NET是一种基于.NET Framework的服务器端编程模型,用于构建动态Web应用程序。其内置对象是ASP.NET框架的核心组成部分,提供了一套丰富的功能,帮助开发者轻松处理请求、响应、会话、状态管理等各种Web开发任务。...
创建一个简单的ASP.NET页面(.ASPX),使用记事本编辑并输入C#或VB.NET代码,通过本地访问查看运行结果。ASP.NET文件通常包含C#和VB.NET两种版本的代码,便于对比学习。 【C#基础知识】C#是ASP.NET中常用的语言,...
ASP.NET是微软公司开发的一种用于构建动态网站、Web应用程序和Web服务的技术,它基于.NET Framework,为开发者提供了强大而高效的应用程序开发环境。本文件参考将深入探讨ASP.NET的核心概念、关键特性和实用技巧。 ...
1. **ASP.NET Web Forms**:mypetshop项目可能采用了ASP.NET Web Forms模型,这是一个基于控件的模型,允许开发者通过拖放控件来构建网页,类似于传统的桌面应用程序开发。Web Forms会自动处理页面的生命周期和用户...
在学习ASP.NET时,你需要了解以下几个关键知识点: 1. **.NET Framework**: .NET Framework是ASP.NET运行的基础,它包含了类库、公共语言运行时(CLR)以及对Windows操作系统的接口。开发者可以通过.NET Framework...