对由 Microsoft® Internet 信息服务 (IIS) 处理的 Microsoft® ASP.NET 页面的每一个请求都会被移交到 ASP.NET HTTP 管道。HTTP 管道由一系列托管对象组成,这些托管对象按顺序处理请求,并将 URL 转换为纯 HTML 文本。HTTP 管道的入口是 HttpRuntime 类。ASP.NET 结构为辅助进程中的每一个 AppDomain 建立一个此类的实例。(请注意,辅助进程为每一个当前正在运行的 ASP.NET 应用程序维护一个特定的 AppDomain。)html
HttpRuntime 类从内部池中获取 HttpApplication 对象,并安排此对象来处理请求。HTTP 应用程序管理器完成的主要任务就是找到将真正处理请求的类。当请求 .aspx 资源时,处理程序就是页面处理程序,即从 Page 继承的类的实例。资源类型和处理程序类型之间的关联关系存储在应用程序的配置文件中。更确切地说,默认的映射集是在 machine.config 文件的 <httpHandlers> 部分定义的。可是,应用程序能够在本地的 web.config 文件中自定义本身的 HTTP 处理程序列表。如下这一行代码就是用来为 .aspx 资源定义 HTTP 处理程序的。web
<add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/>
扩展名能够与处理程序类相关联,而且更可能是与处理程序工厂类相关联。在全部状况下,负责处理请求的 HttpApplication 对象都会得到一个实现 IHttpHandler 接口的对象。若是根据 HTTP 处理程序来解析关联的资源/类,则返回的类将直接实现接口。若是资源被绑定处处理程序工厂,则还须要额外的步骤。处理程序工厂类实现 IHttpHandlerFactory 接口,此接口的 GetHandler 方法将返回一个基于 IHttpHandler 的对象。数据库
HTTP 运行时是如何结束这个循环并处理页面请求的?ProcessRequest 方法在 IHttpHandler 接口中很是重要。经过对表明被请求页面的对象调用此方法,ASP.NET 结构会启动将生成浏览器输出的进程。编程
特定页面的 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 处理程序的基类。mvc
还有一种状况,HTTP 处理程序也不是基于 Page 的,即在应用程序配置文件的 <pages> 部分中,包含了 PageBaseType 属性的从新定义。框架
<pages PageBaseType="Classes.MyPage, mypage" />
PageBaseType 属性指明包含页面处理程序的基类的类型和程序集。从 Page 导出的这个类能够自动赋予处理程序扩展的自定义方法和属性集。ide
彻底识别 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 ,
实例化(Instantiate):控件在页面或其它控件经过调用其构造函数所实例化时。只有当一个控件在加入控件树中后,该步骤后的全部阶段才会发生。
初始化(Initialize):在此阶段中,控件树中的页面与所有控件经过默认的方式调用OnInit方法来触发Init事件,并完成初始化工做。在整个生命周期以前,页面首先创建初始的控件树;在初始阶段以前,为控件赋值。能够实现Page_Init方法来对页面的初始化进行影响,也能够重载控件的OnInit方法来为控件提供初始化逻辑。在这个阶段,控件能够访问其包含的子控件,但却不能访问其父控件或更高层次的控件。
开始跟踪视图状态(Begin Tracking View State):这个阶段发生在初始化阶段的末属阶段。在该阶段中,页面自动调用控件的TrackViewState方法,从而启用视图跟踪。当控件提供复杂的属性时,能够重载该方法。
加载视图状态(仅用于回传过程)(Load View state):这个过程发生在回传时,而不是初始请求过程当中。在此阶段中,控件会将其状态恢复到上一次请求处理完成以后的状态,同时,页面框架自动恢复ViewState字典。
加载回传数据(仅用于回传过程,为可选项)(Load Postback Data):只在控件经过实现IPostBackDataHandler接口参与了回传数据处理时,这个阶段才发生在回传中。在这个阶段中,控件经过从已发送的表单数据中利用IPostBackDataHandler接口的LoadPostData方法更新其状态。
加载(Load):直至该阶段开始,页面中全部控件都已被初始化,回恢复到它们先前周期的最后状态。]
引起修改事件(仅用于回传过程,可选项):只有在控件经过实现IPostBackDataHandler接口参与回传数据处理时,此阶段才会发和在回传中。在些阶段中,控件经过引起事件做为一种信号,即控件状态因为回传而修改。为了参与此阶段,控件必须实现IPostBackDataHandler接口的RaisePostDataChangedEvent方法。
引起回传事件(仅用于回传过程,可选项):只有在控件经过实现IPostBackEventHandler接口参与回传事件处理时,此阶段才会发生在回传中。在此阶段,能够经过[实现IPostBackEventHandler接口的RaisePostBackEvent方法来实现逻辑,以便把客房事件映射到服务器端事件。
预生成(PreRender):在此阶段中,应该经过重载OnPreRender方法,执行在生成控件以前所须要的任何工做。
保存视图状态(Save View State):在此阶段,页面框架自动保存ViewState字典,若是控件须要自定义状态管理,必须经过重载SaveViewState方法来实现自定义状态恢复。这种方法只被EEnableViewState属性为真的控件所调用。
生成(Render)
卸载(Unload)
释放(Dispose)
============================================================================
通常来讲,页要经历下表概述的各个阶段。除了页生命周期阶段之外,在请求先后还存在应用程序阶段,可是这些阶段并不特定于页。有关更多信息,请参见 ASP.NET 应用程序生命周期概述。
一、页请求
页请求发生在页生命周期开始以前。用户请求页时,ASP.NET 将肯定是否须要分析和编译页(从而开始页的生命周期),或者是否能够在不运行页的状况下发送页的缓存版本以进行响应。
二、开始
在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将肯定请求是回发请求仍是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性。
三、页初始化
页初始化期间,可使用页中的控件,并将设置每一个控件的 UniqueID 属性。此外,任何主题都将应用于页。若是当前请求是回发请求,则回发数据还没有加载,而且控件属性值还没有还原为视图状态中的值。
四、加载
加载期间,若是当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。
五、验证
在验证期间,将调用全部验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。
六、回发事件处理
若是请求是回发请求,则将调用全部事件处理程序。
七、呈现
在呈现以前,会针对该页和全部控件保存视图状态。在呈现阶段中,页会针对每一个控件调用 Render 方法,它会提供一个文本编写器,用于将控件的输出写入页的 Response 属性的 OutputStream 中。
八、卸载
彻底呈现页并已将页发送至客户端、准备丢弃该页后,将调用卸载。此时,将卸载页属性(如 Response 和 Request)并执行清理。
在页生命周期的每一个阶段中,页将引起可运行您本身的代码进行处理的事件。对于控件事件,经过以声明方式使用属性(如 onclick)或以使用代码的方式,都可将事件处理程序绑定到事件。
页还支持自动事件链接,即,ASP.NET 将查找具备特定名称的方法,并在引起了特定事件时自动运行这些方法。若是 @ Page 指令的 AutoEventWireup 属性设置为 true(或者未定义该属性,由于该属性默认为 true),页事件将自动绑定至使用 Page_事件的命名约定的方法(如 Page_Load 和 Page_Init)。有关自动事件链接的更多信息,请参见 ASP.NET Web 服务器控件事件模型。
下表列出了最经常使用的页生命周期事件。除了列出的事件外还有其余事件;不过,大多数页处理方案不使用这些事件。而是主要由 ASP.NET 网页上的服务器控件使用,以初始化和呈现它们自己。若是要编写本身的 ASP.NET 服务器控件,则须要详细了解这些阶段。有关建立自定义控件的信息,请参见 开发自定义 ASP.NET 服务器控件。
0一、PreInit
使用该事件来执行下列操做:
检查 IsPostBack 属性来肯定是否是第一次处理该页。
建立或从新建立动态控件。
动态设置主控页。
动态设置 Theme 属性。
读取或设置配置文件属性值。
注意
若是请求是回发请求,则控件的值还没有从视图状态还原。若是在此阶段设置控件属性,则其值可能会在下一事件中被重写。
0二、Init
在全部控件都已初始化且已应用全部外观设置后引起。使用该事件来读取或初始化控件属性。
0三、InitComplete
由 Page 对象引起。使用该事件来处理要求先完成全部初始化工做的任务。
0四、PreLoad
若是须要在 Load 事件以前对页或控件执行处理,请使用该事件。
在 Page 引起该事件后,它会为自身和全部控件加载视图状态,而后会处理 Request 实例包括的任何回发数据。
0五、Load
Page 在 Page 上调用 OnLoad 事件方法,而后以递归方式对每一个子控件执行相同操做,如此循环往复,直到加载完本页和全部控件为止。
使用 OnLoad 事件方法来设置控件中的属性并创建数据库链接。
0六、控件事件
使用这些事件来处理特定控件事件,如 Button 控件的 Click 事件或 TextBox 控件的 TextChanged 事件。
注意
在回发请求中,若是页包含验证程序控件,请在执行任何处理以前检查 Page 和各个验证控件的 IsValid 属性。
0七、LoadComplete
对须要加载页上的全部其余控件的任务使用该事件。
0八、PreRender
在该事件发生前:
Page 对象会针对每一个控件和页调用 EnsureChildControls。
设置了 DataSourceID 属性的每一个数据绑定控件会调用 DataBind 方法。有关更多信息,请参见下面的数据绑定控件的数据绑定事件。
页上的每一个控件都会发生 PreRender 事件。使用该事件对页或其控件的内容进行最后更改。
0九、SaveStateComplete
在该事件发生前,已针对页和全部控件保存了 ViewState。将忽略此时对页或控件进行的任何更改。
使用该事件执行知足如下条件的任务:要求已经保存了视图状态,但未对控件进行任何更改。
十、Render
这不是事件;在处理的这个阶段,Page 对象会在每一个控件上调用此方法。全部 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。
若是建立自定义控件,一般要重写此方法以输出控件的标记。不过,若是自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不须要重写 Render 方法。有关更多信息,请参见 开发自定义 ASP.NET 服务器控件。
用户控件(.ascx 文件)自动合并呈现,所以不须要在代码中显式呈现该控件。
十一、Unload
该事件首先针对每一个控件发生,继而针对该页发生。在控件中,使用该事件对特定控件执行最后清理,如关闭控件特定数据库链接。
对于页自身,使用该事件来执行最后清理工做,如:关闭打开的文件和数据库链接,或完成日志记录或其余请求特定任务。
注意
在卸载阶段,页及其控件已被呈现,所以没法对响应流作进一步更改。若是尝试调用方法(如 Response.Write 方法),则该页将引起异常。
=============================================================================
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
#region OnPreInit 第一步
protected override void OnPreInit(EventArgs e)
{
//检查 IsPostBack 属性来肯定是否是第一次处理该页。
//建立或从新建立动态控件。
//动态设置主控页。
//动态设置 Theme 属性。
//读取或设置配置文件属性值。
//注意
//若是请求是回发请求,则控件的值还没有从视图状态还原。若是在此阶段设置控件属性,则其值可能会在下一事件中被重写。
base.OnPreInit(e);
}
#endregion
#region OnInit 第二步
protected override void OnInit(EventArgs e)
{
//在全部控件都已初始化且已应用全部外观设置后引起。使用该事件来读取或初始化控件属性。
base.OnInit(e);
}
#endregion
#region OnInitComplete 第三步
protected override void OnInitComplete(EventArgs e)
{
//由 Page 对象引起。使用该事件来处理要求先完成全部初始化工做的任务。
base.OnInitComplete(e);
}
#endregion
#region PreLoad 第四步
protected override void OnPreLoad(EventArgs e)
{
//若是须要在 Load 事件以前对页或控件执行处理,请使用该事件。
//在 Page 引起该事件后,它会为自身和全部控件加载视图状态,而后会处理 Request 实例包括的任何回发数据。
base.OnPreLoad(e);
}
#endregion
#region OnLoad 第五步
protected override void OnLoad(EventArgs e)
{
//Page 在 Page 上调用 OnLoad 事件方法,而后以递归方式对每一个子控件执行相同操做,如此循环往复,直到加载完本页和全部控件为止。
//使用 OnLoad 事件方法来设置控件中的属性并创建数据库链接。
base.OnLoad(e);
}
#endregion
#region 控件事件 第六步
protected void Button1_Click(object sender, EventArgs e)
{
//用这些事件来处理特定控件事件,如 Button 控件的 Click 事件或 TextBox 控件的 TextChanged 事件。
//注意
//在回发请求中,若是页包含验证程序控件,请在执行任何处理以前检查 Page 和各个验证控件的 IsValid 属性。
}
#endregion
#region OnLoadComplete 第七步
protected override void OnLoadComplete(EventArgs e)
{
//对须要加载页上的全部其余控件的任务使用该事件。
base.OnLoadComplete(e);
}
#endregion
#region OnPreRender 第八步
protected override void OnPreRender(EventArgs e)
{
//在该事件发生前:
//Page 对象会针对每一个控件和页调用 EnsureChildControls。
//设置了 DataSourceID 属性的每一个数据绑定控件会调用 DataBind 方法。有关更多信息,请参见下面的数据绑定控件的数据绑定事件。
//页上的每一个控件都会发生 PreRender 事件。使用该事件对页或其控件的内容进行最后更改。
base.OnPreRender(e);
}
#endregion
#region SaveStateComplete 第九步
protected override void OnSaveStateComplete(EventArgs e)
{
//在该事件发生前,已针对页和全部控件保存了 ViewState。将忽略此时对页或控件进行的任何更改。
//使用该事件执行知足如下条件的任务:要求已经保存了视图状态,但未对控件进行任何更改。
base.OnSaveStateComplete(e);
}
#endregion
#region Render 第十步
//Render
//这不是事件;在处理的这个阶段,Page 对象会在每一个控件上调用此方法。全部 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。
//若是建立自定义控件,一般要重写此方法以输出控件的标记。不过,若是自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不须要重写 Render 方法。有关更多信息,请参见开发自定义 ASP.NET 服务器控件。
//用户控件(.ascx 文件)自动合并呈现,所以不须要在代码中显式呈现该控件。
#endregion
#region OnUnload 第十一步
protected override void OnUnload(EventArgs e)
{
//该事件首先针对每一个控件发生,继而针对该页发生。在控件中,使用该事件对特定控件执行最后清理,如关闭控件特定数据库链接。
//对于页自身,使用该事件来执行最后清理工做,如:关闭打开的文件和数据库链接,或完成日志记录或其余请求特定任务。
//注意
//在卸载阶段,页及其控件已被呈现,所以没法对响应流作进一步更改。若是尝试调用方法(如 Response.Write 方法),则该页将引起异常。
base.OnUnload(e);
}
#endregion
}
引用键接:http://www.cnblogs.com/oletan/archive/2008/11/04/1326587.html
http://www.cnblogs.com/chinamvc/archive/2009/08/16/1547000.html
出处:http://www.cnblogs.com/luckdv/articles/1691631.html