對由 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