原文链接:http://msdn.microsoft.com/zh-cn/library/ms178472(v=vs.110).aspx 对应版本:.NET 4.0
ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。 这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。 了解页生命周期非常重要,因为这样做您就能在生命周期的合适阶段编写代码,以达到预期效果。
如果您要开发自定义控件,就必须熟悉页生命周期,以便正确进行控件初始化,使用视图状态数据填充控件属性以及运行控件行为代码。 控件的生命周期基于页的生命周期,但是页引发许多您需要在自定义控件中处理的事件。
本主题包含以下各节:
一般来说,页要经历下表概述的各个阶段。 除了页生命周期阶段以外,在请求前后还存在应用程序阶段,但是这些阶段并不特定于页。 Introduction to the ASP.NET Application Life Cycle and ASP.NET Application Life Cycle Overview for IIS 7.0.‘ data-guid="bb26d1217029bf5f80e6ca2eaa93b578">有关更多信息,请参见 Introduction to the ASP.NET Application Life Cycle and IIS 7.0 的 ASP.NET 应用程序生命周期概述(ASP.NET 应用程序生命周期简介)。
生命周期的某些部分仅当页处理为回发时才出现。 UpdatePanel control) as it is during a full-page postback.‘ data-guid="1ca778427ae3364f3b235b23ba0f0938">对于回发,部分页回发过程中(当您使用 UpdatePanel 控件)与整页回发过程中的页生命周期是一样。
阶段 |
说明 |
---|---|
页请求 |
页请求发生在页生命周期开始之前。 用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应。 |
启动 |
Request and Response are set.‘ data-guid="b8042b5472664a3dea367cc9ae3a52dd">在启动阶段,将设置页属性,如 Request 和 Response。 IsPostBack property.‘ data-guid="6791cf57b32b2977068179cbc455299c">在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。 UICulture property.‘ data-guid="e495b403b9ce96c693abce59ebc17d35">页还设置 UICulture 属性。 |
初始化 |
页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。 如果需要,还会向页应用于母版页和主题。 如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。 |
加载 |
加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。 |
回发事件处理 |
如果请求是回发请求,则将调用控件事件处理程序。 Validate method of all validator controls is called, which sets the IsValid property of individual validator controls and of the page.‘ data-guid="52b4383ceaa7494d714b8471472b9fd3">之后,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。 |
呈现 |
在呈现之前,会针对该页和所有控件保存视图状态。 在呈现阶段中,页会针对每个控件调用 Render 方法,它会提供一个文本编写器,用于将控件的输出写入页的 Response 属性的 OutputStream 对象中。 |
卸载 |
Unload event is raised after the page has been fully rendered, sent to the client, and is ready to be discarded.‘ data-guid="7f619d7296024cccb6e39b5d3bb5fb53">完全呈现页并已将页发送至客户端、准备丢弃该页后,将引发 Unload 事件。 Response and Request are unloaded and cleanup is performed.‘ data-guid="5e56b32eedcab292a8b4f246449783fb">此时,将卸载页属性(如 Response 和 Request)并执行清理。 |
在页生命周期的每个阶段中,页将引发可运行您自己的代码进行处理的事件。 onclick, or in code.‘ data-guid="ff85142ff51351621a9e0ee6860c86c8">对于控件事件,通过以声明方式使用特性(如 onclick)或以使用代码的方式,均可将事件处理程序绑定到事件。
页还支持自动事件连接,即,ASP.NET 将查找具有特定名称的方法,并在引发了特定事件时自动运行这些方法。 AutoEventWireup attribute of the @ Page directive is set to true, page events are automatically bound to methods that use the naming convention of Page_event, such as Page_Load and Page_Init.‘ data-guid="7c60aa8921170ff03d140e5e53b699d6">如果 @ Page 指令的 AutoEventWireup 特性设置为 true,页事件将自动绑定至使用命名约定 Page_事件(如Page_Load 和 Page_Init)的方法。 ASP.NET Web Server Control Event Model.‘ data-guid="363d2a27078ae66fce7e2f5be2538ed3">有关自动事件连接的更多信息,请参见 ASP.NET Web 服务器控件事件模型。
下表列出了最常用的页生命周期事件。 除了列出的事件外还有其他事件;不过,大多数页处理方案不使用这些事件。 而是主要由 ASP.NET 网页上的服务器控件使用,以初始化和呈现它们本身。 如果要编写自定义 ASP.NET 服务器控件,则需要详细了解这些事件。 Developing Custom ASP.NET Server Controls.‘ data-guid="d80aa4a51a333665834f9ce6d34e08d0">有关创建自定义控件的信息,请参见开发自定义 ASP.NET 服务器控件。
页事件 |
典型使用 |
---|---|
在启动阶段完成之后、初始化阶段开始之前引发。 使用该事件来执行下列操作:
|
|
在所有控件都已初始化且已应用所有外观设置后引发。 Init event of individual controls occurs before the Init event of the page.‘ data-guid="7226c8915e9cf37bc4ed8b6d62f147f6">各个控件的 Init 事件在页的 Init 事件之前发生。 使用该事件来读取或初始化控件属性。 |
|
在页的初始化阶段结束时引发。 Init and InitComplete events: tracking of view state changes is turned on.‘ data-guid="60c588d208ec9a16fc0df8255b17f470">Init 和 InitComplete 事件之间仅发生一个操作:开启对视图状态更改的跟踪。 ViewState collection.‘ data-guid="4aaf9d2c28f854755f531907a7b16c58">视图状态跟踪使控件可以保留所有以编程方式添加到 ViewState 集合的值。 在开启视图状态跟踪之前,所有添加到视图状态的值都会在回发期间丢失。 Init event.‘ data-guid="aa3c266bb7211fb081bf6b80d9ccc286">控件通常在引发其 Init 事件后立即开启视图状态跟踪。 使用此事件对要在下一个回发后务必保留的视图状态进行更改。 |
|
Request instance.‘ data-guid="ff1666fd6a5323c3b4a3c1cf8533a3f9">在页为自身和所有控件加载视图状态之后以及处理 Request 实例包括的回发数据之后引发。 |
|
Page object calls the OnLoad method on the Page object, and then recursively does the same for each child control until the page and all controls are loaded.‘ data-guid="d6a4f73fb0f32f2e761b1d591632f369">Page 对象对 Page 对象调用 OnLoad 方法,然后以递归方式对每个子控件执行相同操作,直到加载完本页和所有控件为止。 Load event of individual controls occurs after the Load event of the page.‘ data-guid="5b5883b0bd822d469729d3980fa3fd2e">各个控件的 Load 事件在页的 Load 事件之后发生。 OnLoad event method to set properties in controls and to establish database connections.‘ data-guid="6eb57d049a9ca1ececc4411c36d94689">使用 OnLoad 事件方法来设置控件中的属性并建立数据库连接。 |
|
控件事件 |
使用这些事件来处理特定控件事件,如 Button 控件的 Click 事件或 TextBox 控件的 TextChanged 事件。 |
在事件处理阶段结束时引发。 对需要加载页上的所有其他控件的任务使用该事件。 |
|
Page object has created all controls that are required in order to render the page, including child controls of composite controls.‘ data-guid="0d743e4192bd5bfde636ff1c5f0f3457">在 Page 对象创建呈现页所需的所有控件(包括组合控件的子控件)之后引发。 Page object calls EnsureChildControls for each control and for the page.)‘ data-guid="8cb0a33e8fa58c84b784681e98dccd6e">(为此,Page 对象会针对每个控件和页调用 EnsureChildControls。) Page object raises the PreRender event on the Page object, and then recursively does the same for each child control.‘ data-guid="b085d519a3c57c3ace39007bfaba6134">Page 对象在 Page 对象上调用 PreRender 事件,然后以递归方式对每个子控件执行相同操作。 PreRender event of individual controls occurs after the PreRender event of the page.‘ data-guid="39d0b3e75e28e510797c5066ab34485e">各个控件的 PreRender 事件在页的 PreRender 事件之后发生。 在呈现阶段开始之前,使用该事件对页或其控件的内容进行最后更改。 |
|
DataSourceID property is set calls its DataBind method.‘ data-guid="c1f92d61c28b8fcd28cec9ff631b29f5">在设置了 DataSourceID 属性的每个数据绑定控件调用其 DataBind 方法之后引发。 Data Binding Events for Data-Bound Controls later in this topic.‘ data-guid="7f61d04f1bd3328599a1db5bfa2df8e4">有关更多信息,请参见本主题后面的数据绑定控件的数据绑定事件。 |
|
在为页和所有控件保存视图状态和控件状态之后发生。 此时对页或控件进行的任何更改都会影响呈现,但是在下一个回发中将不会检索到这些更改。 |
|
Page object calls this method on each control.‘ data-guid="13088eea13c680a8caf941114a143538">这不是事件;在处理的这个阶段,Page 对象会在每个控件上调用此方法。 所有 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。 如果创建自定义控件,通常要覆盖此方法以输出控件的标记。 Render method.‘ data-guid="c5b88f03c361ce52a460f7c2ca7a3cf4">不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要覆盖 Render 方法。 Developing Custom ASP.NET Server Controls.‘ data-guid="964147618b2bb5445334ffd0587e760f">有关更多信息,请参见开发自定义 ASP.NET 服务器控件。 用户控件(.ascx 文件)自动合并呈现,因此不需要在代码中显式呈现该控件。 |
|
首先针对每个控件引发,继而针对该页引发。 在控件中,使用该事件对特定控件执行最后清理,如关闭控件特定数据库连接。 对于页自身,使用该事件来执行最后清理工作,如:关闭打开的文件和数据库连接,或完成日志记录或其他请求特定任务。 注意
在卸载阶段,页及其控件已被呈现,因此无法对响应流做进一步更改。Response.Write method, the page will throw an exception.‘
data-guid="57ad260379be80f6e4f59109ab856035">如果尝试调用方法(如 Response.Write 方法),则该页将引发异常。
|
各个 ASP.NET 服务器控件都有自己的生命周期,该生命周期与页生命周期类似。 例如,控件的 Init 和 Load 事件在相应的页事件期间发生。
Init and Load recursively occur on each control, they happen in reverse order.‘ data-guid="ebf75b30d74a8e75bb07ee9f8ee47eec">虽然 Init 和 Load 都在每个控件上以递归方式发生,但它们的发生顺序相反。 Init event (and also the Unload event) for each child control occur before the corresponding event is raised for its container (bottom-up).‘ data-guid="da3ffe1ae80a903af83209f13d62b349">每个子控件的 Init 事件(还有 Unload 事件)在为其容器引发相应的事件之前发生(由下到上)。 Load event for a container occurs before the Load events for its child controls (top-down).‘ data-guid="4434b34f8f1475c69818cf0e674db7ac">但是,容器的 Load 事件是在其子控件的 Load 事件之前发生(由上到下)。 Init event occurs before the page Init and Load events, and the master page Load event occurs after the page Init and Load events.‘ data-guid="84a959784e3ab296160e318ed6497854">母版页的行为方式类似于页上的子控件:母版页 Init 事件发生在页的 Init 和 Load 事件之前,母版页 Load 事件发生在页的 Init 和 Load 事件之后。
当您创建从 Page 类继承的类时,除了可以处理由页引发的事件以外,还可以重写页的基类中的方法。 例如,可以覆盖页的 InitializeCulture 方法,以便动态设置区域性信息。 Page_event syntax, the base implementation is implicitly called and therefore you do not need to call it in your method.‘ data-guid="479c7a883fdf921cb9808874b8ab3058">注意,在使用 Page_事件 语法创建事件处理程序时,将隐式调用基实现,因此无需在方法中调用它。 例如,无论是否创建 Page_Load 方法,始终都会调用页基类的 OnLoad 方法。 OnLoad method with the override keyword (Overrides in Visual Basic), you must explicitly call the base method.‘ data-guid="c3258cfea0733e9f9f0ad29857d721c3">但是,如果使用 override 关键字(在 Visual Basic 中为 Overrides)覆盖页的 OnLoad 方法,则必须显式调用基方法。 OnLoad method on the page, you must call base.Load (MyBase.Load in Visual Basic) in order for the base implementation to be run.‘ data-guid="db4f3a79ad5cc7f5cdf6576bb954c6d4">例如,如果在页中覆盖 OnLoad 方法,则必须调用 base.Load(在 Visual Basic 中为 MyBase.Load)以运行基实现。
Page class that you can override in order to add code that executes at specific points in the page life cycle.‘ data-guid="d13d57deeedf71f9f279197c66bcd78e">下图显示了 Page 类的一些最重要方法,您可以对其进行重写以便添加在页生命周期的特定点执行的代码。 Page class.) The illustration also shows how these methods relate to page events and to control events.‘ data-guid="2c13269d261822ffc5cd4a8fbd9d07cf">(有关页方法和事件的完整列表,请参见 Page 类。)该图还演示这些方法如何与页事件和控件事件相关。 在该图中方法和事件的顺序为从上到下排列,在每行中为从左到右。
如果控件是在运行时动态创建的,或者是以声明方式在数据绑定控件的模板中创建的,它们的事件最初与页上的其他控件的事件并不同步。 Init and Load events might occur much later in the page life cycle than the same events for controls created declaratively.‘ data-guid="14d93de48e4425b0f9651c02ec39a858">例如,对于运行时添加的控件,Init 和 Load 事件在页生命周期中的发生时间可能要比以声明方式创建的控件的相同事件晚得多。 Controls collection.‘ data-guid="81b59b33be401044adb0f86ffa98b7b7">因此,从实例化那一刻起,动态添加的控件的事件就一直是在模板中的控件的事件之后发生,直到赶上该控件加入 Controls 集合时所对应事件为止。
GridView, DetailsView, and FormView controls.‘ data-guid="59473a0bccede9fbbc50333481bcf55b">为了帮助您理解页生命周期与数据绑定事件之间的关系,下表列出了数据绑定控件(如 GridView、DetailsView 和 FormView 控件)中与数据相关的事件。
控件事件 |
典型使用 |
---|---|
在控件的 PreRender 事件(该事件在页的 PreRender 事件之后发生)之后引发。 DataSourceID property is set declaratively.‘ data-guid="dc717bd566a680fb12a0ce13b402bc04">(这将应用于以声明方式设置其属性的DataSourceID 控件。 否则,该事件在您调用控件的 DataBind 方法时发生。) 该事件标记将控件绑定到数据的进程的开始。 使用此事件可以手动打开数据库连接,如果需要,还可以在运行查询之前动态设置参数值。 |
|
RowCreated (GridView only) or ItemCreated (DataList, DetailsView, SiteMapPath, DataGrid, FormView, Repeater, and ListView controls)‘ data-guid="b4ced6a02fa21c8335e742ae2fb254c0">RowCreated (仅限 GridView)或ItemCreated(DataList、DetailsView、SiteMapPath、DataGrid、FormView、Repeater 和ListView 控件) |
在控件的 DataBinding 事件之后引发。 使用该事件来操作不依赖于数据绑定的内容。 GridView control.‘ data-guid="419ed2ea28447c4f1f81f268f691ffa9">例如,在运行时,可以以编程方式向 GridView 控件中的页眉或页脚行添加格式。 |
RowDataBound (GridView only) or ItemDataBound (DataList, SiteMapPath, DataGrid, Repeater, and ListView controls)‘ data-guid="fe568226a14d8779d144c2e7e73b3c1b">RowDataBound (仅限 GridView)或ItemDataBound(DataList、SiteMapPath、DataGrid、Repeater 和 ListView 控件) |
在控件的 RowCreated 或 ItemCreated 事件之后引发。 FilterExpression property on child data source controls in order to display related data within the row or item.‘ data-guid="6e348497c2292e1d8163e158f8636691">当此事件发生时,行或项中的数据可用,因此,可以在子数据源控件上格式化数据或设置 FilterExpression 属性,以便显示行或项中的相关数据。 |
在数据绑定控件中的数据绑定操作结尾引发。 GridView control, data binding is complete for all rows and any child controls.‘ data-guid="c519d16ed3f2279c25069ec4bd37e72d">在 GridView 控件中,会为所有行和子控件完成数据绑定。 使用此事件格式化数据绑定内容,或在依赖来自当前控件的内容的值的其他控件中启动数据绑定。 Catch-Up Events for Added Controls earlier in this topic.)‘ data-guid="e3ec2d73af451bd12019fb4bdceda694">(有关更多信息,请参见本主题中前面的“添加的控件的追赶事件”。) |
嵌套的数据绑定控件
如果子控件已执行数据绑定,但其容器控件尚未执行数据绑定,则子控件中的数据与其容器控件中的数据可能不同步。 如果子控件中的数据根据容器控件中的数据绑定值执行了处理,这种情况则尤其显著。
GridView control that displays a company record in each row, and it displays a list of the company officers in a ListBox control.‘ data-guid="cc83c5e4f91ea41641e26582c8c549bb">例如,假定有一个 GridView 控件,它的每一行显示一条公司记录,此外,还有一个 ListBox 控件包含公司管理者列表。 ListBox control to a data source control (such as SqlDataSource) that retrieves the company officer data using the company ID in a query.‘ data-guid="1d9c3b39fa63586f95cabdf78b3260c5">若要填充管理者列表,则需要将 ListBox 控件绑定到一个数据源控件(如 SqlDataSource),后者在查询中使用公司 ID 来检索公司管理者数据。
如果以声明方式设置了 ListBox 控件的数据绑定属性(如 DataSourceID 和 DataMember),ListBox 控件将尝试在包含行的 DataBinding 事件期间绑定到其数据源。 不过,行的 CompanyID 字段直到 GridView 控件的RowDataBound 事件发生后才包含值。 ListBox control) is bound before the containing control (the GridView control) is bound, so their data-binding stages are out of sync.‘ data-guid="4c851c599b242b46c7e6f4decb8ea9d9">这种情况下,先绑定子控件(ListBox 控件),后绑定包含控件(GridView 控件),因此它们的数据绑定阶段并不同步。
ListBox control in the same template item as the ListBox control itself, and do not set the data binding properties of the ListBox declaratively.‘ data-guid="af5be2204113749535569afa79d93c4d">若要避免此种情况,需要将 ListBox 控件的数据源控件与 ListBox 控件自身放在同一模板项中,并且不要以声明方式设置 ListBox 的数据绑定属性。 RowDataBound event, so that the ListBox control does not bind to its data until the CompanyID information is available.‘ data-guid="6cf351e8ee30f51013e18a8daeacfdd4">而应在 RowDataBound 事件期间在运行时以编程方式设置它们,这样,到 CompanyID 信息可用时 ListBox 控件才会绑定到其数据。
Binding to Data Using a Data Source Control.‘ data-guid="035abf39c0a2da795aa921fbb66e9b57">有关更多信息,请参见使用数据源控件绑定到数据。
Login control can use settings in the Web.config file to manage membership authentication automatically.‘ data-guid="396f22d908b3a7f5de4d8ca0eb28ea81">Login 控件可以使用 Web.config 文件中的设置来自动管理成员资格验证。 Login control events relate to the page life cycle, you can use the events listed in the following table.‘ data-guid="f76ee1604084d746849ab2057e44d4d3">不过,如果应用程序要求您自定义控件的工作方式,或者您要了解 Login 控件事件与页生命周期的关联方式,可以使用下表中列出的事件。
控件事件 |
典型使用 |
---|---|
在回发期间,当页的 LoadComplete 事件发生后引发。 此事件标记登录过程的起点。 对必须在验证过程开始前发生的任务使用该事件。 |
|
LoggingIn event. ‘ data-guid="256134aec7c3f726666fa0182d548baf">在 LoggingIn 事件之后引发。 Login control. ‘ data-guid="a2e285048980309405ffb870c2bda182">使用该事件来覆盖或增强 Login 控件的默认验证行为。 |
|
在验证用户名和密码后引发。 使用该事件来重定向到另一个页或动态设置控件中的文本。 如果出现错误或验证失败,就不会发生该事件。 |
|
在身份验证失败的情况下引发。 使用该事件来设置控件中的问题解释文本或将用户定向到不同的页。 |