自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺談ASP.NET頁(yè)面生命周期

開發(fā) 后端
本文介紹由于ASP.NET頁(yè)面生命周期按階段劃分,任務(wù)在不同階段按部就班完成,所以我們的每一個(gè)操作都是階段相關(guān)的,有些操作僅能在特定的階段操作,有些操作在不同階段執(zhí)行會(huì)導(dǎo)致不同的結(jié)果。

ASP.NET的優(yōu)點(diǎn)我說過很多次了,也就是各個(gè)控件獨(dú)立負(fù)責(zé)自己內(nèi)部的邏輯,這是一個(gè)好事情,因?yàn)樗鉀Q了原本ASP處理邏輯耦合度高的問題。然而這是需要代價(jià)的,那就是引入ASP.NET頁(yè)面生命周期,隨著控件的多層嵌套,應(yīng)用的復(fù)雜度增加,我們?cè)俅蜗萑肽嗵叮?/P>

其實(shí)這個(gè)文章題目我兩個(gè)月前就寫下了,可是一直沒想寫完它,直到今天我在這個(gè)泥潭中泡了幾個(gè)小時(shí),于是決定先從泥潭中跳出來把文章寫完,再跳進(jìn)去繼續(xù)解決問題。問題是這樣的:

1. 使用MS AJAX 1.0 Beta2 + 2.0 CTP新建一個(gè)項(xiàng)目,同時(shí)在Bin中放上Beta2的AjaxControlToolkit.dll。
2. 扔上一個(gè)Accordion,放置幾個(gè)AccordionPane,設(shè)置一下CssClass。
3. 在Page_Load中使用Page.LoadControl加載一個(gè)UserControl,然后添加到頁(yè)面上。
4. 接著發(fā)現(xiàn)UserControl內(nèi)的控件無法正常觸發(fā)事件,陷入泥潭中……

首先要說明,如果僅僅做第3步那個(gè)UserControl肯定正常運(yùn)作,那意味著問題出在ScriptManager或Accordion中出現(xiàn)了問題。

想知道到底是什么出問題了嗎?先聽我說說這個(gè)ASP.NET頁(yè)面生命周期的問題吧。

由于ASP.NET頁(yè)面生命周期按階段劃分,任務(wù)在不同階段按部就班完成,所以我們的每一個(gè)操作都是階段相關(guān)的,有些操作僅能在特定的階段操作,有些操作在不同階段執(zhí)行會(huì)導(dǎo)致不同的結(jié)果。當(dāng)然,MS希望盡量消除這些階段間的差異,例如讓一個(gè)操作在盡可能多的階段中都能執(zhí)行,并且盡可能減少在不同階段中操作引發(fā)的不同結(jié)果。然而這不可能完全做到,例如我們都知道ViewState讀寫限制為僅能在某些階段進(jìn)行,于是依賴于ViewState的控件屬性也就因此受到同樣的限制。

控件屬性讀寫受階段限制,這很好接受,對(duì)吧?因?yàn)檫@僅僅是一層依賴關(guān)系。順著依賴關(guān)系推廣出去,情況會(huì)變得越來越復(fù)雜,限制的原因埋藏得越來越底層,接著我們發(fā)現(xiàn)復(fù)雜性這一問題在ASP.NET這種結(jié)構(gòu)良好的體系中出現(xiàn)了,而消滅這種復(fù)雜性的銀彈還沒被發(fā)明。

作為控件或組件的開發(fā)人員,我們當(dāng)然有義務(wù)消除階段差異,讓下游的開發(fā)人員面對(duì)更低的復(fù)雜性,而且我們也確實(shí)盡力去做了??丶拿恳粚臃庋b,都包含著這種努力,并向上承諾盡可能低的階段差異。然而為了讓控件看起來簡(jiǎn)單易用,我們不可能將這些差異完整地記錄在文檔之中,我們嘗試去隱瞞細(xì)節(jié),控件被層層封裝時(shí)我們都這樣做。底層文檔沒告訴我的差異,我當(dāng)然也沒必要寫到這一層的文檔上去;底層文檔提及了的差異,我盡力彌補(bǔ)了,即使彌補(bǔ)得不太好,也不寫到這一層的文檔上去。于是文檔就好像神話傳說一樣隨著世代相傳而改變,最終沒有人知道這個(gè)控件依賴于某些底層的階段差異。

做過控件開發(fā)的人都知道,有時(shí)候我們必須根據(jù)實(shí)際情況采用不同的方式構(gòu)建看起來一樣的控件。例如最簡(jiǎn)單的數(shù)據(jù)控件都會(huì)存在是否PostBack的構(gòu)建差異,如果是非 PostBack,則需要在DataBind時(shí)構(gòu)建并將數(shù)據(jù)保存到ViewState,如果是PostBack則根據(jù)ViewState直接構(gòu)建,如果 PostBack后又遇到了DataBind則需要清除原來的構(gòu)建并重新根據(jù)新數(shù)據(jù)構(gòu)建。再?gòu)?fù)雜一些的控件,還會(huì)分步驟構(gòu)建,默認(rèn)情況下為了消除使用方的階段差異,部分構(gòu)建步驟會(huì)盡可能靠前到Init時(shí)執(zhí)行,而另外一部分構(gòu)建步驟則盡可能推遲到PreRender時(shí)執(zhí)行,中間部分則盡可能減少自己的變化以便使用方操作。然而事情不會(huì)那么簡(jiǎn)單,使用方的某些操作(通常是訪問某個(gè)屬性)如果依賴于某個(gè)構(gòu)建步驟的完成,因此一旦這些操作出現(xiàn),原本在 PreRender才執(zhí)行的特定構(gòu)建步驟就要提前執(zhí)行,當(dāng)這樣的操作在不同階段進(jìn)行多幾次,構(gòu)建步驟就已經(jīng)散落在ASP.NET頁(yè)面生命周期的各階段。

構(gòu)建步驟可能散落于ASP.NET頁(yè)面生命周期的各階段對(duì)于控件設(shè)計(jì)師來說是一個(gè)嚴(yán)峻的問題,這意味著他要保證任何一個(gè)構(gòu)建步驟在任何一個(gè)階段執(zhí)行都是無差異的,當(dāng)然這不可能做到,于是又要引入別的機(jī)制來減少這種差異,復(fù)雜性就此產(chǎn)生了,接下來隨著復(fù)雜性的增加控件設(shè)計(jì)師越來越無法確保較低的階段差異程度,這就到控件使用者遭殃了,如果控件使用者又再把控件封裝,并且依然企圖降低階段差異程度,那么災(zāi)難也就發(fā)生了……

我花了幾個(gè)小時(shí)在泥潭中泡了幾個(gè)小時(shí),邊泡邊寫這篇文章,問題當(dāng)然已經(jīng)有結(jié)果了。

如果Accordion設(shè)置了HeaderCssClass或者ContentCssClass,那就會(huì)出問題,但如果為AccordionPane都加上以上兩個(gè)屬性,又不會(huì)有問題了。這樣的情況當(dāng)然通過用Reflector查看這兩個(gè)類的代碼來解決,結(jié)果發(fā)現(xiàn)Accordion會(huì)檢測(cè)每一個(gè) AccordionPane是否有設(shè)置這兩個(gè)屬性,如果沒有就把AccordionPane的設(shè)置為和自己的一樣。在AccordionPane被設(shè)置時(shí),會(huì)調(diào)用this.EnsureChildControls(),這是一個(gè)會(huì)導(dǎo)致構(gòu)建步驟提前執(zhí)行的方法,于是控件構(gòu)建的順序就改變了,不僅僅 Accordion內(nèi)部的順序改變了,整個(gè)Page的都改變了。由于控件的ID是按順序自動(dòng)分配的,包括我那個(gè)UserControl,構(gòu)建順序的改變意味著ID的改變,也就相當(dāng)于整個(gè)控件樹都改變了,事件當(dāng)然不能正常觸發(fā)。

***的解決方案當(dāng)然是為我那個(gè)UserControl指定ID。我花了那么多個(gè)小時(shí)才發(fā)現(xiàn)自己做了件蠢事,一早打開Trace來看控件樹就應(yīng)該能發(fā)覺UniqueID的變化。

雖然這個(gè)問題看起來不是一個(gè)太好的例子,因?yàn)橐淮蜷_Trace就應(yīng)該能找到問題的來源,但實(shí)際上它卻正好揭示了ASP.NET框架內(nèi)部的“蝴蝶效應(yīng)(Butterfly Effect)”——隨著復(fù)雜度的增加,任何一個(gè)細(xì)微的改變都會(huì)導(dǎo)致全局上的巨大變化。在設(shè)計(jì)ASP.NET的時(shí)候,MS可能也在想著解耦,在簡(jiǎn)單的情況下這東西確實(shí)也解耦,然而在復(fù)雜的情況下卻正好背道而馳,這真的是很諷刺。

【編輯推薦】

  1. 微軟發(fā)布ASP.NET MVC 2預(yù)覽版 多項(xiàng)功能更新
  2. ASP.NET服務(wù)器自定義控件安全準(zhǔn)則
  3. ASP.NET編程規(guī)范之編碼規(guī)范淺析
  4. 關(guān)于ASP.NET Session的一點(diǎn)認(rèn)識(shí)
  5. ASP.NET編程工具ASP.NET Web Matrix詳細(xì)介紹
責(zé)任編輯:佚名 來源: yesky
相關(guān)推薦

2013-04-07 10:42:56

Asp.Net頁(yè)面周期

2009-08-04 16:50:15

ASP.NET頁(yè)面生命

2009-07-31 10:47:18

ASP.NET頁(yè)面生命

2009-08-03 14:18:40

ASP.NET編程模型ASP.NET頁(yè)面生命

2012-08-16 09:38:38

ASP.NET

2009-08-03 14:37:38

ASP.NET編程模型頁(yè)面生命周期

2009-07-23 10:23:44

2009-07-20 10:33:02

ASP.NET MVC

2009-07-23 18:14:17

MVC生命周期

2009-07-31 17:53:39

ASP.NET線程安全

2009-08-10 14:31:46

ASP.NET組件設(shè)計(jì)ASP.NET控件生命

2009-08-04 17:49:31

Web Page生命周ASP.NET Pos

2009-08-07 16:57:17

ASP.NET頁(yè)面生存

2009-02-12 13:16:55

請(qǐng)求生命周期MVCASP.NET

2009-07-28 09:46:53

ASP.NET服務(wù)器控

2009-07-23 18:55:17

ASP.NET頁(yè)生命周

2011-06-21 10:26:37

2010-04-02 09:02:02

ASP.NET MVC

2009-08-04 15:58:06

ASP.NET動(dòng)態(tài)控件

2021-04-26 09:22:07

ASP.NET Cor服務(wù)周期
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)