ASP.NET編程模型之頁面生命周期十一步詳解
ASP.NET編程模型之頁面生命周期1、對象初始化Init事件:
頁面初始化的標(biāo)志是Init事件。頁面中的控件(包括頁面本身)都是在它們最初的Form中被首次初始化的。在成功創(chuàng)建頁面的控件樹后,對應(yīng)用程序激發(fā)這個事件。當(dāng)Init事件發(fā)生時(shí),在.aspx源文件中靜態(tài)聲明的所有控件都以實(shí)例化并取其默認(rèn)值。應(yīng)該注意到,這是還沒有視圖狀態(tài)信息可供使用。雖然可以重載OnInit方法,但是系統(tǒng)并不保證這些控件實(shí)例是按照怎樣的順序被創(chuàng)建的。
ASP.NET編程模型之頁面生命周期2、加載視圖:
在初始化之后,頁面框架立即加載該頁面的視圖狀態(tài)(ViewState)。所謂視圖狀態(tài)就是一些名稱/值對的集合,例如可以保存TextBox控件的ID和Text屬性值。它一般被用于在一個往返行程中存留信息到服務(wù)器,即參與HTTP請求與響應(yīng)。
頁面視圖狀態(tài)被存儲在﹤input type=”hidden”﹥字段中,做為_VIEWSTAE的值進(jìn)行記錄。該視圖狀態(tài)通過ASP.NE自動維護(hù)。通過重寫LoadViewState方法組件,開發(fā)人員可控制如何還原視圖狀態(tài)以及如何將其內(nèi)容影射到內(nèi)部狀態(tài)。LoadViewState方法就是從ViewState中獲取上一次的狀態(tài),并按照頁面的控件樹的結(jié)構(gòu),用遞歸來遍歷整個樹,將對應(yīng)的狀態(tài)恢復(fù)到每一個控件上。
ASP.NET編程模型之頁面生命周期3、處理回發(fā)數(shù)據(jù):
還原了視圖狀態(tài),頁面樹種的各個控件的狀態(tài)就與瀏覽器上次呈現(xiàn)該頁面時(shí)這些控件所處的狀態(tài)相同。下一步需要更新這些控件的狀態(tài)以發(fā)送給客戶端。
回發(fā)數(shù)據(jù)處理階段是各個控件有機(jī)會更新其狀態(tài),以便準(zhǔn)確的反映相應(yīng)的HTML元素在客戶端的狀態(tài)。例如,一個服務(wù)器TextBox控件對應(yīng)的HTML元素是﹤input type=text﹥,在回發(fā)數(shù)據(jù)階段,TextBox控件將檢索﹤input﹥標(biāo)記的當(dāng)前值并用它刷新其內(nèi)部狀態(tài)。每個控件負(fù)責(zé)從以發(fā)送的數(shù)據(jù)中提取相應(yīng)值,并更新其某些屬性。TextBox控件將更新Text屬性,而CheckBox控件將刷新其Checked屬性。服務(wù)器控件和HTML元素之間的匹配關(guān)系由二者的ID確定。
頁框架將在每個提交數(shù)據(jù)的控件上實(shí)現(xiàn)IpostBackDataHandler接口,然后激發(fā)LoadPostData事件,通過頁面解析發(fā)現(xiàn)實(shí)現(xiàn)了IpostBackDataHandle接口的控件,這樣就能正確的回傳數(shù)據(jù)更新控件狀態(tài)。在識別控件時(shí),ASP.NET通過匹配控件的唯一標(biāo)示符來更新正確的控件,該標(biāo)識符具有名稱值集和中的名稱值對。這也就是在所有特定的頁中每個控件都需要一個唯一標(biāo)識符的原因之一。其他的步驟都由框架來完成,例如確定每個標(biāo)識符在環(huán)境中是否唯一以及控件的基本屬性等。
LostPostData方法的原型如下:
- Public virtual bool LoadPostData(string postDatakey, NameValueCollection postCollection)
PostDataKey是標(biāo)識控件的關(guān)鍵字,可以理解為控件的ID,postCollection是包含回發(fā)數(shù)據(jù)的集合,可以理解為視圖狀態(tài)值。該方法返回一個bool值,如果是true,則表示控件狀態(tài)因回發(fā)而更改;否則返回false。頁框架會更跟蹤所有返回true的控件并在這些控件上調(diào)用RaisePostDataChangeEvent事件。
LoadPostData方法是由System..Web.WebControls.Control定義的,而添加的每一個服務(wù)器控件也是從System..Web.WebControls.Control繼承的,所以對于數(shù)據(jù)的回發(fā)處理并不需要干預(yù)。
ASP.NET編程模型之頁面生命周期4、加載頁面Load:
在回發(fā)數(shù)據(jù)處理階段結(jié)束時(shí),頁面中的所有控件都根據(jù)客戶端上所輸入的更改來更新的狀態(tài)。此時(shí),對頁面激發(fā)OnLoad事件。對于這個事件,相信大多數(shù)朋友都會比較熟悉,用Visual Studio.Net生成的頁面中的Page_Load方法就是響應(yīng)Load事件的方法,對于每一次請求,Load事件都會觸發(fā),Page_Load方法也就會執(zhí)行??梢岳迷摲椒▓?zhí)行一些頁面初始化,例如準(zhǔn)備好數(shù)據(jù)庫的連接字符串。在事件引用中,為了提高性能,通常使用Page類的IsPostBack屬性判斷是不是數(shù)據(jù)回發(fā)。
ASP.NET編程模型之頁面生命周期5、回發(fā)更改通知RaisePostDataChanged:
如(3)所述,在所有實(shí)現(xiàn)了IpostBackDataHandler接口的控件被正確的回傳數(shù)據(jù)更新后,每個控件都有一個布爾值的標(biāo)識,標(biāo)識其自上一次提交后改控件的數(shù)據(jù)是被更改還是保持其值。然后ASP.NET通過搜索頁來尋找任何顯示控件數(shù)據(jù)被更改的標(biāo)識并激發(fā)RaisePostDataChanged。RaisePostDataChanged事件直到Load事件發(fā)生后,所有控件被更新后才激發(fā)。這保證了在控件被回傳數(shù)據(jù)更新前,其他控件的數(shù)據(jù)在RaisePostDataChanged事件中沒有被手動更改過。雖然也可以在Page的基礎(chǔ)上自己定義數(shù)據(jù)更改的事件,但通常這個事件由太大用處。
ASP.NET編程模型之頁面生命周期6、 處理回發(fā)事件RaisePostBackEvent:
當(dāng)回傳更新導(dǎo)致數(shù)據(jù)改變而引發(fā)服務(wù)器端事件后,引發(fā)回傳的對象會在RaisePostBackEvent事件中被處理。這種引發(fā)回傳的對象往往是一個按鈕被單擊或者其狀態(tài)改變而引發(fā)回傳的控件。例如Button觸發(fā)樂Onclick事件、客戶端修改了某個文本框的文本、同時(shí)將AutoPostBack設(shè)置為true、觸發(fā)TextChanged事件等。
很多代碼都在這個事件中執(zhí)行,因?yàn)檫@是控制事件驅(qū)動邏輯的理想位置。為了保證呈現(xiàn)到瀏覽器的數(shù)據(jù)的正確性,在一系列的回傳事件后,RaisePostBackEvent事件最終被激發(fā)。基于一致性考慮,會傳中改變的控件直到這個函數(shù)被執(zhí)行后才被更新。在實(shí)際的ASP.NET開發(fā)工作中要做的工作就是在此事件發(fā)生前處理代碼。
ASP.NET編程模型之頁面生命周期7、預(yù)呈現(xiàn)PreRender:
在處理回發(fā)事件后,頁面就準(zhǔn)備進(jìn)行呈現(xiàn)。這一階段的標(biāo)志是PreRender事件。各個控件可利用這個很好的時(shí)機(jī),以便執(zhí)行任何需要在保存視圖狀態(tài)和呈現(xiàn)輸出結(jié)果的前一刻完成得最后一些更新操作。最終請求的處理都會轉(zhuǎn)變?yōu)榘l(fā)揮服務(wù)器的響應(yīng),預(yù)呈現(xiàn)這個階段就是執(zhí)行在最終呈現(xiàn)之前所做的狀態(tài)的更改,因?yàn)樵诔尸F(xiàn)一個控件之前,必須更具它的屬性來產(chǎn)生HTML,比如Style屬性。這是典型的例子,這預(yù)呈現(xiàn)之前,可以更改一個控件的Style,當(dāng)執(zhí)行預(yù)呈現(xiàn)時(shí),就可以把Style保存下來,做為呈現(xiàn)階段顯示HTML的樣式信息。
ASP.NET編程模型之頁面生命周期8、保存狀態(tài)SaveViewState:
下一個狀態(tài)為SaveViewState,在這一狀態(tài)中所有控件以及頁面本身可以刷新自己的SaveState集合的內(nèi)容。所得到的視圖狀態(tài)隨后得以序列化、進(jìn)行哈希運(yùn)算、進(jìn)行Base64編碼并關(guān)聯(lián)到VI-EMSTATE隱藏自端。
ASP.NET編程模型之頁面生命周期9、呈現(xiàn)視圖Render:
到這里,實(shí)際上頁面對請求的處理基本就告一段落了,在Render事件中,也調(diào)用對象是它們呈現(xiàn)為HTML,然后也收集HTML發(fā)送給客戶。客戶接收到HTML標(biāo)記后進(jìn)行重組,最終顯示給客戶。當(dāng)Render事件被重載時(shí),開發(fā)者可以為瀏覽器創(chuàng)建定值的HTML,此時(shí)頁面創(chuàng)建的任何HTML都還沒有生效。Render方法用HtmlTextWriter對象做參數(shù)并由它產(chǎn)生HTML送給瀏覽器。這主要用于自定義控件的開發(fā)。
ASP.NET編程模型之頁面生命周期10、處置Disposed:
執(zhí)行銷毀控件前的所有最終清理操作。在此階段必須釋放對昂貴資源的引用,如內(nèi)存的退出、數(shù)據(jù)庫的連接等。
ASP.NET編程模型之頁面生命周期11、卸載Unload:
一個頁面的最后生存標(biāo)志就是Unload事件,該事件在頁面對象被解除之前發(fā)生。在此事件中,可以調(diào)用Dispose方法盡可能釋放占用的任何關(guān)鍵資源(例如,文件、圖形對象以及數(shù)據(jù)庫連接)。
ASP.NET編程模型之頁面生命周期的詳細(xì)內(nèi)容就介紹完了,希望對你了解ASP.NET編程模型之頁面生命周期有所幫助。
【編輯推薦】