轉載http://www.cnblogs.com/dotnetnuke/archive/2008/09/28/1301406.html
對於ASP.NET開發者,理解ASP.NET的頁面生命週期是非常重要的。主要是爲了搞明白在哪裏放置特定的方法和在何時設置各種頁面屬性。但是記憶和理解頁面生命週期裏提供的事件處理方法(method)非常困難。互聯網上有很多關於頁面生命週期內部機制的文章,所以本文只准備簡單覆蓋技術的基礎部分,更主要的目的是給大家提供一個簡單得記憶頁面生命週期的方法。
準確的記憶ASP.NET頁面生命週期每一個階段發生了什麼事情是比較困難的,一種便於記憶的方法是根據各個階段的名字組合出一個縮寫。微軟的文檔給出的ASP.NET生命週期如下:
- Page Request
- Start
- Page Initialization
- Load
- Validation
- Postback event handling
- Rendering
- Unload
根據這個組合出一個縮寫非常容易。既然Page Request技術上並不是頁面生命週期的一部分(這個階段僅僅標示我們是否開始一個頁面週期或者從緩存加載一個頁面),我們爲了方便,就不包括這一階段。
- S – Start
- I – Initialize
- L – Load
- V – Validate
- E – Event Handling
- R – Render
這樣就組合出一個縮寫“SILVER',這個英文單詞非常好記。當然,一定要記住頁面生命週期的最後一個環節unload沒有包括在裏面。如果你覺得有必要,你可以記憶爲“SILVER-U”或者“SILVER-YOU",儘管有點破壞這個記憶法的完美性。現在,我們非常容易就記住了頁面生命週期,接着我們總結一下每一步都發生了什麼,都有什麼事件伴隨着發生。
1. Start
在這個階段,頁面屬性,比如Request
, Response
, IsPostBack
和UICulture被創建。最爲一個開發人員,大部分時候在這個階段你不需要做任何事。 如果你需要調用或者重寫(override)這一階段的行爲,可以使用PreInit方法創建或者重新創建動態控件,設置master page或者theme或者讀取和設置profile property的值。要注意的一點是,如果是回傳(postback)的頁面請求,所有控件的值還沒有從view state裏還原,如果你在這個階段設置一個控件的值,這個值有可能在下面的階段被重寫並覆蓋。
2. Initialize
這個階段對於開發人員是很重要。在這個階段,theme被應用,所有的控件都被設置了唯一的ID。開發人員在這個階段可以調用Init
, InitComplete
和PreLoad
方法。微軟關於這些方法使用的建議如下:
Init
– 這個事件發生在所有控件被初始化並且皮膚設置也被應用後。使用這個事件來讀取控件的初始化值。InitComplete
–這個事件被Page對象觸發,使用這個事件處理那些要求所有初始化工作都完成後才能做的事情。PreLoad
- 如果在頁面或者控件進入Load事件前你有什麼要處理的,使用這個事件。Page在觸發這個事件後,Page就會爲自己和所有的控件加載view state並且處理所有Request中的postback數據。
3. Load
這個階段可能是開發者使用得最多的一個階段。在這個階段,所有的控件被viewstate中信息填充並被加載,OnLoad事件被觸發。在這個階段你可以爲頁面上所有的服務端控件設置屬性,得到query strings,建立數據庫連接。
4. Validation
如果你的控件要求驗證,驗證會在這個階段發生,這個時候你可以檢查控件的IsValid屬性。跟這個階段關聯的事件是Validate,它有一個可以接受驗證字符串羣的重載方法(overload method),這個重載方法執行特定控件羣的驗證。
5. Event Handling
所有服務器端控件的事件處理髮生在這個階段。也就是說Click
, SelectedIndexChanged
等等這些事件會應用到你的服務器端控件,如果是頁面請求是回傳(postback)的話,這些事件的處理函數就會被控件觸發。這個階段可以使用的事件如下:
LoadComplete
– 在這個階段,頁面上所有的控件加載完畢。PreRender
– 這裏有幾個重點,第一:頁面對象(page object)會調用每一個控件的EnsureChildControls函數,並最終調用自己的。其次:所有具有DataSourceID的數據綁定控件都會調用自己的DataBind函數。要注意的一點是,PreRender事件會發生在一個頁面的每一個控件上。在這個事件的最後,頁面和所有控件的ViewState被存儲。SaveStateComplete
– 到這裏,ViewState已經存儲完畢,如果你有什麼操作不需要修改控件但需要修改ViewState的,可以放在SaveStateComplete裏面。
6. Render
渲染(Render)實際上不是一個事件,頁面對象調用每一個控件的Render方法從而按順序的輸出控件的HTML代碼。編寫用戶自定義控件的開發者對這個階段最感興趣了,因爲輸出用戶自定義HTML代碼的標準做法就是重寫Render方法。如果你的控件是從ASP.NET服務器端控件繼承來的,你也許不需要重寫Render方法,除非你想呈現一個與用戶控件默認行爲不同的行爲。這些都超出這個文檔要討論的範圍了,如果想了解更多,請參考Microsoft's Developing Custom ASP.NET Server Controls. (http://msdn2.microsoft.com/en-us/library/zt27tfhy.aspx)
7. Unload
最後這個事件首先是被各個控件逐一觸發,最後被頁面觸發。在這個時刻,所有的控件已經被渲染爲輸出流(output stream)並且無法被修改。這個階段中,任何試圖對response stream的操作都會引發異常。這個事件主要用於做一些清理工作,比如關閉數據庫連接和打開的文件或者登記事件記錄等等其它任務。
頁面週期中都有哪些方法
下面列出ASP.NET頁面生命週期中所有的方法,這些方法都可以被重寫(override),要注意的是這些方法有的會遞歸調用,有個會被頁面中的內容重複調用,這個列表是按照頁面加載時最通用的順序排列的。
Construct
ProcessRequest
FrameworkInitialize
InitializeCulture
- If child controls are present:
AddParsedSubObject
CreateControlCollection
AddedControl
ResolveAdapter
DeterminePostBackMode
OnPreInit
OnInit
TrackViewState
OnInitComplete
OnPreLoad
OnLoad
OnLoadComplete
EnsureChildControls
CreateChildControls
OnPreRender
OnPreRenderComplete
SaveViewState
OnSaveStateComplete
CreateHtmlTextWriter
RenderControl
Render
RenderChildren
VerifyRenderingInServerForm
OnUnload
Dispose
結論
在開發ASP.NET程序時,瞭解什麼時候發生什麼事情是非常重要的。理解頁面中事件是如何層層展開節省大量撓頭和查錯的時間。當這些頁面週期中的事件難以記住時,我希望這個使用的法子能幫助你梳理出在程序裏哪個地方需要做什麼處理。
我寫這篇文章是爲了幫助大家,也方便了自己。即使是熟練的開發人員有時也會忘記那些先那些後。這篇文章不是面面俱到,而是希望給初學者和中級水平的開發者提供一些“小技巧”,從而幫助他們避免一些基本的錯誤。