您當前位置>首頁 » 新聞資訊 » 技(jì)術(shù)分(fēn)享 >
記不(bù)住ASP.NET頁面生(shēng)命周期的(de)苦惱
發表時(shí)間(jiān):2020-10-18
發布人(rén):葵宇科(kē)技(jì)
浏覽次數(shù):46
對(duì)于ASP.NET開(kāi)發者,理(lǐ)解ASP.NET的™§¶(de)頁面生(shēng)命周期是(shì)非常重要(yào)的(de)。主要(yà ₩÷λo)是(shì)為(wèi)了(le)搞明(míng)白(bái)在哪裡(lǐ)放(fàng)置特±¶↕定的(de)方法和(hé)在何時(shí)設置各種頁面屬'γ性。但(dàn)是(shì)記憶和(hé)理(lǐ)解頁面生(shēng)命周期裡>≠↕©(lǐ)提供的(de)事(shì)件(jiàn)處理(lǐ)方法(m$↓σδethod)非常困難。互聯網上(shàng)有(yǒu)很(hěn)多(du↕≥ō)關于頁面生(shēng)命周期內(nèi)部機(jī₩α)制(zhì)的(de)文(wén)章(zhāng),所以本文(wén)隻準備簡單覆蓋技(♦¶≠jì)術(shù)的(de)基礎部分(fēn),更主要(yàoβγ)的(de)目的(de)是(shì)給大(dà)家(jiā)提供一(yī)個(gè)↑←δ簡單得(de)記憶頁面生(shēng)命周期的(de)方法。
昆明(míng)軟件(jiàn)開(kāi)發公司中的(de)佼佼者,緻力定制(zhì)軟件(jiàn)開(kāi)發,昆明(míng)軟件(jiàn)開(kāi)發請(q ★δǐng)聯系昆明(míng)葵宇科(kē)技(jì)有(yǒu)限公司,電(dià÷ n)話(huà):15987118523。
準确的(de)記憶ASP.NET頁面生(shēng)命周期每一(yī)個(g↔₹♠è)階段發生(shēng)了(le)什(shén)麽事(shì)情是(shì)比較困難的(de&×"↑),一(yī)種便于記憶的(de)方法是(shì)根¶•§據各個(gè)階段的(de)名字組合出一(yī)個(gè)縮寫。微(wēi)軟的(de)σ☆×文(wén)檔給出的(de)ASP.NET生(shēng)命周期如(rú)下(xià):
Page Request
Start
Page Initialization
Load
Validation
Postback event handling
Rendering
Unload
根據這(zhè)個(gè)組合出一(yī)個(gè)縮寫非常容易。既然Page Request→&&γ技(jì)術(shù)上(shàng)并不(bù)是(shì)∏÷頁面生(shēng)命周期的(de)一(yī)部分(fēn)(這(zhè)個(gè)階段僅僅标←♠α™示我們是(shì)否開(kāi)始一(yī)個(gè)>£π頁面周期或者從(cóng)緩存加載一(yī)個(gè)頁面),我們為(wèi)了(∑↕ le)方便,就(jiù)不(bù)包括這(zhè)一(yī)階段。
S – Start
I – Initialize
L – Load
V – Validate
E – Event Handling
R – Render
這(zhè)樣就(jiù)組合出一(yī)個(gè)縮寫&ldq↓>uo;SILVER',這(zhè)個(gè)英文(wén)單詞非常好(hǎo) >記。當然,一(yī)定要(yào)記住頁面生(shēng)命周期的(de≥→ ±)最後一(yī)個(gè)環節unload沒有(yǒu)包括在裡(lǐ)面€"。如(rú)果你(nǐ)覺得(de)有(yǒu)必要(yào),你'€γ>(nǐ)可(kě)以記憶為(wèi)“SILVERγ$©≠-U”或者“SILVER-YOU">±;,盡管有(yǒu)點破壞這(zhè)個(gè)記憶&€♦法的(de)完美(měi)性。現(xiàn)在,我們非常容易就(jiù)記住了(→÷le)頁面生(shēng)命周期,接著(zhe)我們總結一(yī)下(xià)←β每一(yī)步都(dōu)發生(shēng)了(le)什(shén)麽,都(≈✘ε÷dōu)有(yǒu)什(shén)麽事(shì)件(jiàn)伴随著(zhe)<±←發生(shēng)。
1. Start
在這(zhè)個(gè)階段,頁面屬性,比如(rú)Request, Response, I↕ ∏δsPostBack和(hé)UICulture 被創建。最為(wèi)一€♦"β(yī)個(gè)開(kāi)發人(rén)員(yuán),大(dà)部分(fēn)時Ω >(shí)候在這(zhè)個(gè)階段你(nǐ)不(bù)需要(yào)做(zu ≈ò)任何事(shì)。如(rú)果你(nǐ)需要(yào)調用(yòng)或者重≤σ≠寫(override)這(zhè)一(yī)階段的(de)行(xíng)為(wèi),可(kě) ₩≥₹以使用(yòng)PreInit方法創建或者重新創建動态控件(j↔≥iàn),設置master page或者theme或者讀(dú)取和(hé)設置profil<♣©♠e property的(de)值。要(yào)注意的(de)αγπ>一(yī)點是(shì),如(rú)果是(shì)回傳(po∞¶stback)的(de)頁面請(qǐng)求,所有(yǒu)控件(j₽¥iàn)的(de)值還(hái)沒有(yǒu)從(cóng)view±© state裡(lǐ)還(hái)原,如(rú)果你(nǐ)在這(zhè)個(gè)階段設置↔☆÷一(yī)個(gè)控件(jiàn)的(de)值,這(zhè)個(gè)值有(yǒu↑π€)可(kě)能(néng)在下(xià)面的(de)階段被重寫并覆→蓋
2. Initialize
這(zhè)個(gè)階段對(duì)于開(kāi)發人(rén)員(yuán)'↔✔σ是(shì)很(hěn)重要(yào)。在這(zhè)個(gè)階段,theme被應用(yòng£<™α),所有(yǒu)的(de)控件(jiàn)都(dōu)被設置了(α€le)唯一(yī)的(de)ID。開(kāi)發人(rén)員(yuán)在這(zhè)個(gè↔)階段可(kě)以調用(yòng)Init, InitComp<¶lete和(hé)PreLoad 方法。微(wēi)軟關于這(☆≥'zhè)些(xiē)方法使用(yòng)的(de)建☆↓£¥議(yì)如(rú)下(xià):
Init – 這(zhè)個(gè)事(shì)件(jiàn)發©©↓€生(shēng)在所有(yǒu)控件(jiàn)被初始化(huà)并且皮膚設置也(yě)被應用(§←♣yòng)後。使用(yòng)這(zhè)個(gè)事(shì)件(jiàn)來(l×ái)讀(dú)取控件(jiàn)的(de)初始化(huà)επ值。
InitComplete – 這(zhè)個(gè)事(shì)件(jiàn)被P∏σage對(duì)象觸發,使用(yòng)這(zhè)個(gè)事(shì)件(jiàn)處理(Ω₽lǐ)那(nà)些(xiē)要(yào)求所有(yǒu)初始化(huà)工(♦≈§gōng)作(zuò)都(dōu)完成後才能(néng¶¥₹)做(zuò)的(de)事(shì)情。
PreLoad - 如(rú)果在頁面或者控件(jiàn)進入Load事(shì)件€φ✘(jiàn)前你(nǐ)有(yǒu)什(shén)麽要(yào)處理(lǐ)的(δ₩∏de),使用(yòng)這(zhè)個(gè)事(shì)件(jiàn)。Pa¥↓β≈ge在觸發這(zhè)個(gè)事(shì)件(jiàn)後,P '"→age就(jiù)會(huì)為(wèi)自(zì)己和(hé) <₩ε所有(yǒu)的(de)控件(jiàn)加載view₹φφ state并且處理(lǐ)所有(yǒu)Request中的(d♦"≤e)postback數(shù)據。
3. Load
這(zhè)個(gè)階段可(kě)能(néng)是(shì)開(kπ₹σāi)發者使用(yòng)得(de)最多(duō)的(de)一(yī)個(gè)階↕γ段。在這(zhè)個(gè)階段,所有(yǒu)的(de)©'$↑控件(jiàn)被viewstate中信息填充并被加載,OnLoad事(shì)件(jiànεγ)被觸發。在這(zhè)個(gè)階段你(nǐ)可(kě)以為(wèi)頁α↑面上(shàng)所有(yǒu)的(de)服務端控件(jiàn)設置屬性,< 得(de)到(dào)query strings,建立數(shù)據庫連接。
4. Validation
如(rú)果你(nǐ)的(de)控件(jiàn)要(yào)求驗證,驗≥→ 證會(huì)在這(zhè)個(gè)階段發生(sh£σα©ēng),這(zhè)個(gè)時(shí)候你(nǐ)可¶→(kě)以檢查控件(jiàn)的(de)IsValid屬性。跟這(zhè)個(gè)階段關聯的(d €∞e)事(shì)件(jiàn)是(shì)Validate,它有(yǒu)一(yī)個(gè)可∑γ♣(kě)以接受驗證字符串群的(de)重載方法(overload mλ±σ"ethod),這(zhè)個(gè)重載方法執行(xí$←∏ng)特定控件(jiàn)群的(de)驗證。
5. Event Handling
所有(yǒu)服務器(qì)端控件(jiàn)的(de)事(shì)件(jiàn)處理↑≈→(lǐ)發生(shēng)在這(zhè)個(gè)階段。也(yě)就(jiù ₽)是(shì)說(shuō)Click, SelectedIndexChanged等等這(zh£ ≠è)些(xiē)事(shì)件(jiàn)會(huì)應用(yòng)到(dào)你(nǐπ↔★<)的(de)服務器(qì)端控件(jiàn),如(rú)果是&↑"γ(shì)頁面請(qǐng)求是(shì)回傳(postback)的(de)話(huà),< ¥這(zhè)些(xiē)事(shì)件(jiàn)的(de)處理(lǐ)函數(β∞shù)就(jiù)會(huì)被控件(jiàn)觸™×發。這(zhè)個(gè)階段可(kě)以使用(yòng)的(de)事(shì)件(jiàn)如£¶☆↑(rú)下(xià):
LoadComplete – 在這(zhè)個(gè)階段,頁面上(shàn↔♥¥γg)所有(yǒu)的(de)控件(jiàn)加載完畢
PreRender – 這(zhè)裡(lǐ)有(yǒu)幾個(gè)↑Ω∞重點,第一(yī):頁面對(duì)象(page object)會(huì)調用(yòn↕₹'g)每一(yī)個(gè)控件(jiàn)的(de)EnsureChildCo ≈☆πntrols函數(shù),并最終調用(yòng)自(zì)己的(de)。其次:所有(yǒu ♣π)具有(yǒu)DataSourceID的(de)數(shù)據綁定控件(jiàn)都(♦₹dōu)會(huì)調用(yòng)自(zì)己的(de)DataBind函數ε£ &(shù)。要(yào)注意的(de)一(yī)點是(shì),PreRender事(sh'™₹ ì)件(jiàn)會(huì)發生(shēng)在一(yī)個(gè)頁面的(₹>♦©de)每一(yī)個(gè)控件(jiàn)上(shàng)。在這(÷↕☆♥zhè)個(gè)事(shì)件(jiàn)的(de)最後,頁面和(hé)所有(yǒu)控™ε件(jiàn)的(de) ViewState被存儲。
SaveStateComplete – 到(dào)這(zhè)裡✔• (lǐ),ViewState已經存儲完畢,如(rú)果你(nǐ)有(yǒu)什(&Ω≥"shén)麽操作(zuò)不(bù)需要(yào)修改控件(jλ₽↑iàn)但(dàn)需要(yào)修改ViewState的∑ π(de),可(kě)以放(fàng)在SaveStateComplete裡(lǐ)面 ★✔>。
6. Render
渲染(Render)實際上(shàng)不(bù ÷)是(shì)一(yī)個(gè)事(shì)件(jiàn),頁面對(duì)象調用(yòn₹÷λg)每一(yī)個(gè)控件(jiàn)的(de)Ren σα der方法從(cóng)而按順序的(de)輸出控件(jiàn)的∞¶(de)HTML代碼。編寫用(yòng)戶自(zì)定義控 ↓>件(jiàn)的(de)開(kāi)發者對(duì)這(zhè)個(gè)階段最感興趣了(le),→€∞因為(wèi)輸出用(yòng)戶自(zì)定義HTML代★↓<碼的(de)标準做(zuò)法就(jiù)是(shì)重寫€∏Render方法。如(rú)果你(nǐ)的(de)控件(jiàn)"ε®φ是(shì)從(cóng)ASP.NET服務器(qì)端控件(jiàn)≥↕→☆繼承來(lái)的(de),你(nǐ)也(yě)許不(bù)需λφ要(yào)重寫Render方法,除非你(nǐ)想呈現(xiàn)一(y≠<ī)個(gè)與用(yòng)戶控件(jiàn)默認行(xíng)為(wèi)不(bù§ )同的(de)行(xíng)為(wèi)。這(zhè)些(xiē)都(dōu)超出這(zhè)個(€•↔gè)文(wén)檔要(yào)討(tǎo)論的(de)π♥範圍了(le),如(rú)果想了(le)解更多(duō),請(qǐng)參考 Microso≥±≥ft's Developing Custom ASP.NET☆©∏ Server Controls. ( http://msdn2.microsoft.★"™/zt27com/en-us/librarytfhy.aspx)
7. Unload
最後這(zhè)個(gè)事(shì)件(jiàn)首先是(shì)被各個(gè)控件(∏↑★jiàn)逐一(yī)觸發,最後被頁面觸發。在這(zhè)個(gè)時(sh$©í)刻,所有(yǒu)的(de)控件(jiàn)已經被渲染為(wèi)輸出流(outp←∞™ut stream)并且無法被修改。這(zhè)個(gè)階段中,任何試圖對ε₩★(duì)response stream的(de)操作(zuò)都(dōu)會(huì)引發異常。®↑≥±這(zhè)個(gè)事(shì)件(jiàn)主要(yào)用(yòng)于做(× zuò)一(yī)些(xiē)清理(lǐ)工(gōng)作(zuò),比如(rú)關閉數(₽>♠shù)據庫連接和(hé)打開(kāi)的(de)文(wén)件(jiε→àn)或者登記事(shì)件(jiàn)記錄等等其它任務。
頁面周期中都(dōu)有(yǒu)哪些(xiē)方法
下(xià)面列出ASP.NET頁面生(shēng)命周♦¶期中所有(yǒu)的(de)方法,這(zhè)些(xiē)方法都(dōu)≥δ∏可(kě)以被重寫(override),要(yào)注意的(de)是(shì)這(zhè>♠×♣)些(xiē)方法有(yǒu)的(de)會(huì)遞歸★<Ω調用(yòng),有(yǒu)個(gè)會(huì)被頁面中的(de)內(nèi)容重複調用(₹•≤•yòng),這(zhè)個(gè)列表是(shì)按照(zhào)頁面加載時(shí)最通(←§tōng)用(yòng)的(de)順序排列的(de)。
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
VerifyRenderingInServerFo∏∞γ→rm
OnUnload
Dispose
結論
在開(kāi)發ASP.NET程序時(shí),了(le)解什(shénε©☆)麽時(shí)候發生(shēng)什(shén)麽事(shì'•↓•)情是(shì)非常重要(yào)的(de)。理(lǐ)解頁面中§★事(shì)件(jiàn)是(shì)如(rú)何層層展開(kāi)₽δ節省大(dà)量撓頭和(hé)查錯(cuò)的(de)時(sh↓♣&φí)間(jiān)。當這(zhè)些(xiē)頁面周期中的(de)事(shì)件★€©φ(jiàn)難以記住時(shí),我希望這(zhè)個(gè)×↓使用(yòng)的(de)法子(zǐ)能(néng)幫助你(nǐ)梳理(lΩ©ǐ)出在程序裡(lǐ)哪個(gè)地(dì)方需要(yào)做(z&↔uò)什(shén)麽處理(lǐ)。
我寫這(zhè)篇文(wén)章(zhāng)是(shì)為(wèi)↔δ 了(le)幫助大(dà)家(jiā),也(yě)方便了(l↔§ e)自(zì)己。即使是(shì)熟練的(de)開(kāi)發人(rén)員(yuán)有(ε €yǒu)時(shí)也(yě)會(huì)忘記那(nà)些(xiγ©σ♠ē)先那(nà)些(xiē)後。這(zhè)篇文(wén≈₽ €)章(zhāng)不(bù)是(shì)面面俱到(dào),而是(♥Ω♥shì)希望給初學者和(hé)中級水(shuǐ)平的₹®(de)開(kāi)發者提供一(yī)些(xiē)&ldq♣×uo;小(xiǎo)技(jì)巧”,從(cóng)而幫助他(tā) λ們避免一(yī)些(xiē)基本的(de)錯(cuò←ε>)誤