asp.net頁(yè)面生命周期詳解
Asp.net是微軟.Net戰(zhàn)略的一個(gè)組成部分。它相對(duì)以前的Asp有了很大的發(fā)展,引入了許多的新機(jī)制。本文就Asp.net頁(yè)面的生命周期向大家做一個(gè)初步的介紹,以期能起到指導(dǎo)大家更好、更靈活地操縱Asp.net的作用。當(dāng)一個(gè)獲取網(wǎng)頁(yè)的請(qǐng)求(可能是通過(guò)用戶(hù)提交完成的,也可能是通過(guò)超鏈接完成的)被發(fā)送到Web服務(wù)器后,這個(gè)頁(yè)面就會(huì)接著運(yùn)行從創(chuàng)建到處理完成的一系列事件。在我們?cè)噲D建立Asp.net頁(yè)面的時(shí)候,這個(gè)執(zhí)行周期是不必去考慮的,那樣只會(huì)自討苦吃。然而,如果被正確的操縱,一個(gè)頁(yè)面的執(zhí)行周期將是一道有效而且功能強(qiáng)大的工具。許多開(kāi)發(fā)者在編寫(xiě)Asp.net的頁(yè)面以及用戶(hù)控件的時(shí)候發(fā)現(xiàn),如果知道整個(gè)過(guò)程中發(fā)生了什么以及在什么時(shí)候發(fā)生將對(duì)完成整個(gè)任務(wù)起到很重要的幫助作用。下面我就向大家介紹一下一個(gè)Asp.net頁(yè)面從創(chuàng)建到處理完成過(guò)程中的十個(gè)事件。同時(shí),也向大家展示如何在這些事件中添加自己的代碼以達(dá)到預(yù)定的效果。
一.初始化對(duì)象
一個(gè)頁(yè)面的控件(以及頁(yè)面本身)最初應(yīng)被正確的初始化。通過(guò)在你的C#文件的構(gòu)造函數(shù)中聲名所有對(duì)象(如圖1),頁(yè)面就知道要?jiǎng)?chuàng)建多少對(duì)象以及它們的類(lèi)型。一旦你在你的構(gòu)造函數(shù)中聲名了所有的對(duì)象,你就可以通過(guò)繼承類(lèi)、方法、事件或是屬性訪(fǎng)問(wèn)它們。然而,如果你的一些對(duì)象是在Aspx文件中指定的一些控件,那么這些控件就沒(méi)有屬性可言了。同時(shí),通過(guò)代碼訪(fǎng)問(wèn)它們會(huì)產(chǎn)生一些意外的錯(cuò)誤,因?yàn)檫@些控件實(shí)例是沒(méi)有一個(gè)確定的創(chuàng)建順序的(如果它們是被一起創(chuàng)建的)。還有,你可以通過(guò)OnInit來(lái)重載初始化事件。
二.導(dǎo)入Viewstate數(shù)據(jù)
在初始化事件后,所有控件只可以通過(guò)它們的ID被引用訪(fǎng)問(wèn)(因?yàn)檫€沒(méi)有相應(yīng)的DOM可使用)。在LoadViewState這個(gè)事件中,所有的控件將獲得它們的第一個(gè)屬性:Viewstate屬性。這個(gè)屬性最終將被返回給服務(wù)器以判斷這個(gè)頁(yè)面是已經(jīng)被用戶(hù)訪(fǎng)問(wèn)完畢還是仍然在被用戶(hù)所訪(fǎng)問(wèn)。Viewstate屬性以“名稱(chēng)/值”對(duì)的字符串方式被保存,它包含了控件的文本以及值等信息。該屬性被存儲(chǔ)在一個(gè)隱藏的<input>控件的值屬性里,在請(qǐng)求頁(yè)面時(shí)被傳遞。這種方式比起Asp3.0的維持、判斷頁(yè)面狀態(tài)的方式有了很大的進(jìn)步啊。還有,你可以重載LoadViewState事件函數(shù)來(lái)對(duì)相應(yīng)的控件進(jìn)行值設(shè)定。
三.用LoadPostData處理Postback數(shù)據(jù)
在頁(yè)面創(chuàng)建的這個(gè)階段,服務(wù)器對(duì)頁(yè)面上的控件提交的表單數(shù)據(jù)(在Asp.net中稱(chēng)postback數(shù)據(jù))進(jìn)行處理。當(dāng)一個(gè)頁(yè)面提交一個(gè)表單時(shí),框架就在每個(gè)提交了數(shù)據(jù)的控件上執(zhí)行一個(gè)IPostBackDataHandler接口操作。然后頁(yè)面執(zhí)行LoadPostData事件,解析頁(yè)面,找到每個(gè)執(zhí)行了IpostBackDataHandler接口操作的控件,并用恰當(dāng)?shù)膒ostback數(shù)據(jù)更新這些控件狀態(tài)。Asp.net是通過(guò)用NameValue集中的“名稱(chēng)/值”對(duì)和每個(gè)控件的唯一的ID匹配來(lái)實(shí)現(xiàn)這一操作的。所以,在Asp.net的頁(yè)面上每個(gè)控件必須有一個(gè)唯一的ID,不可以出現(xiàn)幾個(gè)控件共有ID的情況。即使是用戶(hù)自定義的一些控件,框架也會(huì)賦予它們各自唯一的ID的。在LoadPostData事件后,就要執(zhí)行下面的RaisePostDataChanged事件了。
四.導(dǎo)入對(duì)象
在Load事件中,對(duì)象都實(shí)例化了。所有的對(duì)象第一次被布置在DOM頁(yè)面(在Asp.net中稱(chēng)控件樹(shù))里了并且可以通過(guò)代碼或是相關(guān)的位置被引用。這樣,對(duì)象就可以很容易的從客戶(hù)端獲得諸如寬度、高度、值、可見(jiàn)性等在Html中的屬性值。在Load事件中,當(dāng)然還有像設(shè)置控件屬性等操作的發(fā)生。這個(gè)過(guò)程是整個(gè)生命周期中最重要、最主要的,你可以通過(guò)調(diào)用OnLoad來(lái)重載Load事件,
五.RaisePostBackChanged事件
就像在上面提到的那樣,這個(gè)事件是發(fā)生在所有的控件執(zhí)行了IPostBackDataHandler接口操作并被正確的postback數(shù)據(jù)更新后的。在這個(gè)過(guò)程中,每個(gè)控件都被賦予一個(gè)布爾值來(lái)標(biāo)志該控件有沒(méi)有被更新。然后,Asp.net就在整個(gè)頁(yè)面上尋找任何已被更新過(guò)的控件并執(zhí)行RaisePostDataChanged事件操作。不過(guò),這個(gè)事件是要在所有的控件都被更新了以及Load事件完成后才進(jìn)行的。這樣就保證了一個(gè)控件在被postback數(shù)據(jù)更新前,別的控件在RaisePostDataChanged事件中是不會(huì)被手動(dòng)改變的。
六.處理客戶(hù)端PostBack事件
當(dāng)由postback數(shù)據(jù)在服務(wù)器端引起的事件都完成后,產(chǎn)生postback數(shù)據(jù)的對(duì)象就執(zhí)行RaisePostBackEvent事件操作??墒菚?huì)有這種情況,由于一個(gè)控件狀態(tài)的改變使得它將表單返回給服務(wù)器或是用戶(hù)點(diǎn)擊了提交按鈕使得表單返回給服務(wù)器。在這種情況下應(yīng)該有相應(yīng)的處理代碼來(lái)體現(xiàn)事件驅(qū)動(dòng)這一面向?qū)ο螅∣OP)編程原則。由于要滿(mǎn)足呈現(xiàn)給瀏覽器的數(shù)據(jù)的精確性要求,在一系列postback事件中RaisePostBackEvent事件是最后發(fā)生的。
在postback過(guò)程中改變的控件不應(yīng)在執(zhí)行功能函數(shù)被調(diào)用后更新。也就是說(shuō),任何由于一個(gè)預(yù)期的事件而改變的數(shù)據(jù)應(yīng)該在最終的頁(yè)面上被反映出來(lái)。你可以通過(guò)修改RaisePostBackEvent函數(shù)來(lái)滿(mǎn)足你的要求,
七.預(yù)先呈遞對(duì)象
可以改變對(duì)象并將改變保存的最后時(shí)刻就是這一步――預(yù)先呈遞對(duì)象。這樣,你可以在這一步對(duì)控件的屬性、控件樹(shù)結(jié)構(gòu)等作出最后的修改。同時(shí)還不用考慮Asp.net對(duì)其作出任何改變,因?yàn)榇藭r(shí)已經(jīng)脫離了數(shù)據(jù)庫(kù)調(diào)用以及viewstate更新了。在這一步之后,對(duì)對(duì)象的所有修改將最終被確定,不能被保存到頁(yè)面的viewstate中了。你可以通過(guò)OnPreRender來(lái)重載這一步。
八.保存ViewState
所有對(duì)頁(yè)面控件的修改完成后viewstate就被保存了。對(duì)像的狀態(tài)數(shù)據(jù)還是保留在隱藏的<input>控件里面,呈現(xiàn)給Html的對(duì)象狀態(tài)數(shù)據(jù)也是從這里取得的。在SaveViewState事件中,其值能被保存到viewstate對(duì)象,然而這時(shí)在頁(yè)面上控件的修改卻不能了。你可以用SaveViewState來(lái)重載這一步
九.呈遞給Html
運(yùn)用Html創(chuàng)建給瀏覽器輸出的頁(yè)面的時(shí)候Render事件就發(fā)生了。在Render事件過(guò)程中,頁(yè)面調(diào)用其中的對(duì)象將它們呈遞給Html。然后,頁(yè)面就可以以Html的形式被用戶(hù)的瀏覽器訪(fǎng)問(wèn)了。當(dāng)Render事件被重載時(shí),開(kāi)發(fā)者可以編寫(xiě)自定義的Html代碼使得原先生成的Html都無(wú)效而按照新的Html來(lái)組織頁(yè)面。Render方法將一個(gè)HtmlTextWriter對(duì)象作為參數(shù)并用它將Html在瀏覽器上以網(wǎng)頁(yè)的形式顯示。這時(shí)仍然可以做一些修改動(dòng)作,不過(guò)它們只是客戶(hù)端的一些變化而已了。你可以重載Render事件
十.銷(xiāo)毀對(duì)象
在呈遞給Html完成后,所有的對(duì)象都應(yīng)被銷(xiāo)毀。在Dispose事件中,你應(yīng)該銷(xiāo)毀所有在建立這個(gè)頁(yè)面時(shí)創(chuàng)建的對(duì)象。這時(shí),所有的處理已經(jīng)完畢,所以銷(xiāo)毀任何剩下的對(duì)象都是不會(huì)產(chǎn)生錯(cuò)誤的,包括頁(yè)面對(duì)象。你可以重載Dispose事件
全文總結(jié)
以上就是Asp.net頁(yè)面生命周期中的十個(gè)事件。每次我們請(qǐng)求一個(gè)Asp.net頁(yè)面時(shí),我們都經(jīng)歷著同樣的過(guò)程:從初始化對(duì)象到銷(xiāo)毀對(duì)象。通過(guò)了解Asp.net頁(yè)面的內(nèi)部運(yùn)行機(jī)制,我相信大家在編寫(xiě)、調(diào)試代碼的時(shí)候會(huì)更加游刃有余的。
相關(guān)文章
ASP.NET2.0緩存(Cache)技術(shù)深入理解
緩存技術(shù)是ASP.NET2.0非常重要的一個(gè)特性,它提供了一種非常好的本地?cái)?shù)據(jù)緩存機(jī)制,從而有效的提高數(shù)據(jù)訪(fǎng)問(wèn)的性能2012-11-11asp.net生成靜態(tài)頁(yè)并分頁(yè)+ubb
編程思路生成靜態(tài)頁(yè)其實(shí)只有內(nèi)容部分是需要分頁(yè)的,生成靜態(tài)頁(yè)并分頁(yè)的步驟是在textarea或者在線(xiàn)編輯器中,需要分頁(yè)的地方就插入一個(gè)[ page ]2008-10-10ASP.NET在IIS上注冊(cè)報(bào)0x800702e4錯(cuò)誤解決方法
報(bào)一個(gè)0x800702e4 請(qǐng)求的操作需要提升的錯(cuò)誤。解決的方法和前面大同小異,給這個(gè)aspnet_regiis.exe創(chuàng)建一個(gè)快捷方式,給它的目標(biāo)后面加上 一個(gè)-i,再右擊這個(gè)快捷方式,以管理員身份運(yùn)行,就行了2012-08-08asp.net System.Guid ToString五種格式
這篇文章主要介紹了asp.net System.Guid ToString五種格式,需要的朋友可以參考下2017-02-02asp.net 讀取并修改config文件實(shí)現(xiàn)代碼
讀取并修改 config 文件的asp.net代碼,方便我們用asp.net修改配置文件。2009-11-11DataList中TextBox onfocus調(diào)用后臺(tái)void靜態(tài)方法及獲取相應(yīng)行數(shù)
DataList中我放了一個(gè)TextBox 現(xiàn)在的問(wèn)題是當(dāng)我光標(biāo)放到TextBox上的時(shí)候。如果讓onfocus調(diào)用后臺(tái)某一個(gè)void靜態(tài)方法并且在靜態(tài)方法里邊獲取光標(biāo)相應(yīng)的DataList的相應(yīng)行數(shù),本文介紹如何實(shí)現(xiàn),感興趣的朋友可以了解下2013-01-01VS2019中.NET如何實(shí)現(xiàn)打日志功能
本文主要介紹了VS2019中.NET如何實(shí)現(xiàn)打日志功能,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03log4net創(chuàng)建系統(tǒng)日志的詳細(xì)步驟
log4net是.Net下一個(gè)非常優(yōu)秀的開(kāi)源日志記錄組件。log4net記錄日志的功能非常強(qiáng)大。它可以將日志分不同的等級(jí),以不同的格式,輸出到不同的媒介。本文主要是簡(jiǎn)單的介紹如何在Visual Studio2010(Asp.Net Mvc3.0)中使用log4net快速創(chuàng)建系統(tǒng)日志,如何擴(kuò)展以輸出自定義字段2013-11-11