.net頁面生命週期

       ASP.NET 頁運行時,此頁將經歷一個生命週期,在生命週期中將執行一系列處理步驟。這些步驟包括初始化、實例化控件、還原和維護狀態、運行事件處理程序代碼以及進行呈現。瞭解頁的生命週期非常重要,這樣就能在合適的生命週期階段編寫代碼,以達到預期效果。此外,如果開發自定義控件,則必須熟悉頁生命週期,從而正確地初始化控件,使用視圖狀態數據填充控件屬性以及運行所有控件行爲邏輯。
      

    (1)對象初始化Init事件:頁面初始化的標誌是Init事件。頁面中的控件(包括頁面本身)都是在它們最初的Form中被首次初始化的。在成功創建頁面的控件樹後,對應用程序激發這個事件。當Init事件發生時,在.aspx源文件中靜態聲明的所有控件都以實例化並取其默認值。應該注意到,這是還沒有視圖狀態信息可供使用。雖然可以重載OnInit方法,但是系統並不保證這些控件實例是按照怎樣的順序被創建的。

    (2)加載視圖:在初始化之後,頁面框架立即加載該頁面的視圖狀態(ViewState)。所謂視圖狀態就是一些名稱/值對的集合,例如可以保存TextBox控件的ID和Text屬性值。它一般被用於在一個往返行程中存留信息到服務器,即參與HTTP請求與響應。

頁面視圖狀態被存儲在<input type=”hidden”>字段中,做爲_VIEWSTAE的值進行記錄。該視圖狀態通過ASP.NE自動維護。通過重寫LoadViewState方法組件,開發人員可控制如何還原視圖狀態以及如何將其內容影射到內部狀態。LoadViewState方法就是從ViewState中獲取上一次的狀態,並按照頁面的控件樹的結構,用遞歸來遍歷整個樹,將對應的狀態恢復到每一個控件上。

    (3)處理回發數據:還原了視圖狀態,頁面樹種的各個控件的狀態就與瀏覽器上次呈現該頁面時這些控件所處的狀態相同。下一步需要更新這些控件的狀態以發送給客戶端。

回發數據處理階段是各個控件有機會更新其狀態,以便準確的反映相應的HTML元素在客戶端的狀態。例如,一個服務器TextBox控件對應的HTML元素是<input type=text>,在回發數據階段,TextBox控件將檢索<input>標記的當前值並用它刷新其內部狀態。每個控件負責從以發送的數據中提取相應值,並更新其某些屬性。TextBox控件將更新Text屬性,而CheckBox控件將刷新其Checked屬性。服務器控件和HTML元素之間的匹配關係由二者的ID確定。

頁框架將在每個提交數據的控件上實現IpostBackDataHandler接口,然後激發LoadPostData事件,通過頁面解析發現實現了IpostBackDataHandle接口的控件,這樣就能正確的回傳數據更新控件狀態。在識別控件時,ASP.NET通過匹配控件的唯一標示符來更新正確的控件,該標識符具有名稱值集和中的名稱值對。這也就是在所有特定的頁中每個控件都需要一個唯一標識符的原因之一。其他的步驟都由框架來完成,例如確定每個標識符在環境中是否唯一以及控件的基本屬性等。

LostPostData方法的原型如下:

Public virtual bool LoadPostData(string postDatakey, NameValueCollection postCollection)

PostDataKey是標識控件的關鍵字,可以理解爲控件的ID,postCollection是包含回發數據的集合,可以理解爲視圖狀態值。該方法返回一個bool值,如果是true,則表示控件狀態因回發而更改;否則返回false。頁框架會更跟蹤所有返回true的控件並在這些控件上調用RaisePostDataChangeEvent事件。

LoadPostData方法是由System..Web.WebControls.Control定義的,而添加的每一個服務器控件也是從System..Web.WebControls.Control繼承的,所以對於數據的回發處理並不需要干預。

    (4)加載頁面Load:在回發數據處理階段結束時,頁面中的所有控件都根據客戶端上所輸入的更改來更新的狀態。此時,對頁面激發OnLoad事件。對於這個事件,相信大多數朋友都會比較熟悉,用Visual Studio.Net生成的頁面中的Page_Load方法就是響應Load事件的方法,對於每一次請求,Load事件都會觸發,Page_Load方法也就會執行。可以利用該方法執行一些頁面初始化,例如準備好數據庫的連接字符串。在事件引用中,爲了提高性能,通常使用Page類的IsPostBack屬性判斷是不是數據回發。

    (5)回發更改通知RaisePostDataChanged:如(3)所述,在所有實現了IpostBackDataHandler接口的控件被正確的回傳數據更新後,每個控件都有一個布爾值的標識,標識其自上一次提交後改控件的數據是被更改還是保持其值。然後ASP.NET通過搜索頁來尋找任何顯示控件數據被更改的標識並激發RaisePostDataChanged。RaisePostDataChanged事件直到Load事件發生後,所有控件被更新後才激發。這保證了在控件被回傳數據更新前,其他控件的數據在RaisePostDataChanged事件中沒有被手動更改過。雖然也可以在Page的基礎上自己定義數據更改的事件,但通常這個事件由太大用處。

    (6) 處理回發事件RaisePostBackEvent:當回傳更新導致數據改變而引發服務器端事件後,引發回傳的對象會在RaisePostBackEvent事件中被處理。這種引發回傳的對象往往是一個按鈕被單擊或者其狀態改變而引發回傳的控件。例如Button觸發樂Onclick事件、客戶端修改了某個文本框的文本、同時將AutoPostBack設置爲true、觸發TextChanged事件等。

很多代碼都在這個事件中執行,因爲這是控制事件驅動邏輯的理想位置。爲了保證呈現到瀏覽器的數據的正確性,在一系列的回傳事件後,RaisePostBackEvent事件最終被激發。基於一致性考慮,會傳中改變的控件直到這個函數被執行後才被更新。在實際的ASP.NET開發工作中要做的工作就是在此事件發生前處理代碼。

    (7)預呈現PreRender:在處理回發事件後,頁面就準備進行呈現。這一階段的標誌是PreRender事件。各個控件可利用這個很好的時機,以便執行任何需要在保存視圖狀態和呈現輸出結果的前一刻完成得最後一些更新操作。最終請求的處理都會轉變爲發揮服務器的響應,預呈現這個階段就是執行在最終呈現之前所做的狀態的更改,因爲在呈現一個控件之前,必須更具它的屬性來產生HTML,比如Style屬性。這是典型的例子,這預呈現之前,可以更改一個控件的Style,當執行預呈現時,就可以把Style保存下來,做爲呈現階段顯示HTML的樣式信息。

    (8)保存狀態SaveViewState:下一個狀態爲SaveViewState,在這一狀態中所有控件以及頁面本身可以刷新自己的SaveState集合的內容。所得到的視圖狀態隨後得以序列化、進行哈希運算、進行Base64編碼並關聯到VI-EMSTATE隱藏自端。

    (9)呈現視圖Render:到這裏,實際上頁面對請求的處理基本就告一段落了,在Render事件中,也調用對象是它們呈現爲HTML,然後也收集HTML發送給客戶。客戶接收到HTML標記後進行重組,最終顯示給客戶。當Render事件被重載時,開發者可以爲瀏覽器創建定值的HTML,此時頁面創建的任何HTML都還沒有生效。Render方法用HtmlTextWriter對象做參數並由它產生HTML送給瀏覽器。這主要用於自定義控件的開發。

    (10)處置Disposed:執行銷燬控件前的所有最終清理操作。在此階段必須釋放對昂貴資源的引用,如內存的退出、數據庫的連接等。

    (11) 卸載Unload:一個頁面的最後生存標誌就是Unload事件,該事件在頁面對象被解除之前發生。在此事件中,可以調用Dispose方法儘可能釋放佔用的任何關鍵資源(例如,文件、圖形對象以及數據庫連接)。

 
發佈了17 篇原創文章 · 獲贊 12 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章