国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
頁(yè)面生命周期
#
事件或方法
功能
描述
1
Init 事件
頁(yè)面初始化
頁(yè)面生存周期中的第一個(gè)階段是初始化。當(dāng) Init 事件發(fā)生時(shí),在 .aspx 源文件中靜態(tài)聲明的所有控件都已實(shí)例化并取其默認(rèn)值。應(yīng)該注意的是,這時(shí)視圖狀態(tài)信息還不可用。
2
LoadViewState 方法
加載視圖狀態(tài)
可以重寫 LoadViewState 方法來自定義狀態(tài)還原。
3
LoadPostData 方法
處理回發(fā)數(shù)據(jù)
處理傳入窗體數(shù)據(jù)。
4
Load 事件
加載頁(yè)面
頁(yè)面控件初始化完成并反映了客戶端的數(shù)據(jù)。
5
RaisePostDataChangedEvent 方法
回發(fā)更改通知
引發(fā)更改事件。
6
RaisePostBackEvent 方法
處理回發(fā)事件
處理引起回發(fā)的客戶端事件,并在服務(wù)上引發(fā)相應(yīng)時(shí)間。
7
PreRender 事件
頁(yè)面預(yù)呈現(xiàn)
各個(gè)控件可利用這個(gè)很好的時(shí)機(jī),以便執(zhí)行任何需要在保存視圖狀態(tài)和呈現(xiàn)輸出結(jié)果的前一刻完成的最后一些更新操作。
8
SaveViewState 方法
保存視圖狀態(tài)
將ViewState屬性保存到字符串中,重寫 SaveViewState 方法可以修改 ViewState 屬性。
9
Render 方法
呈現(xiàn)頁(yè)面
重寫 Render 方法,即可更改各個(gè)控件的呈現(xiàn)機(jī)制。該方法獲取一個(gè) HTML 編寫器對(duì)象,并使用該對(duì)象聚集所有將針對(duì)該控件生成的 HTML 文本。Page 類的 Render 方法的默認(rèn)實(shí)現(xiàn)方式包括對(duì)所有成員控件的遞歸調(diào)用。對(duì)于每個(gè)控件,頁(yè)面都調(diào)用 Render 方法并將 HTML 輸出放入高速緩存。
10
Dispose 方法
處置
是否對(duì)昂貴資源的引用。
11
Unload 事件
卸載頁(yè)面
Unload 事件是一個(gè)頁(yè)面的最后生存標(biāo)志,該事件在頁(yè)面對(duì)象被解除之前發(fā)生。在此事件中,您應(yīng)該釋放可能占用的任何關(guān)鍵資源(例如,文件、圖形對(duì)象、數(shù)據(jù)庫(kù)連接)。在此事件之后,瀏覽器收到 HTTP 響應(yīng)數(shù)據(jù)包并顯示頁(yè)面。
當(dāng)一個(gè)頁(yè)面請(qǐng)求發(fā)送到WEB服務(wù)器時(shí),不論該事件是由頁(yè)面提交還是由頁(yè)面重定向而激發(fā)的,頁(yè)面在其被創(chuàng)建到釋放的過程中都會(huì)運(yùn)行一系列的事件。一個(gè)ASP.NET頁(yè)面從被創(chuàng)建到釋放的過程包含10個(gè)事件。
(1)對(duì)象初始化Init事件:頁(yè)面初始化的標(biāo)志是Init事件。頁(yè)面中的控件(包括頁(yè)面本身)都是在它們最初的Form中被首次初始化的。在成功創(chuàng)建頁(yè)面的控件樹后,對(duì)應(yīng)用程序激發(fā)這個(gè)事件。當(dāng)Init事件發(fā)生時(shí),在.aspx源文件中靜態(tài)聲明的所有控件都以實(shí)例化并取其默認(rèn)值。應(yīng)該注意到,這是還沒有視圖狀態(tài)信息可供使用。雖然可以重載OnInit方法,但是系統(tǒng)并不保證這些控件實(shí)例是按照怎樣的順序被創(chuàng)建的。
(2)加載視圖:在初始化之后,頁(yè)面框架立即加載該頁(yè)面的視圖狀態(tài)(ViewState)。所謂視圖狀態(tài)就是一些名稱/值對(duì)的集合,例如可以保存TextBox控件的ID和Text屬性值。它一般被用于在一個(gè)往返行程中存留信息到服務(wù)器,即參與HTTP請(qǐng)求與響應(yīng)。
頁(yè)面視圖狀態(tài)被存儲(chǔ)在<input type=”hidden”>字段中,做為_VIEWSTAE的值進(jìn)行記錄。該視圖狀態(tài)通過ASP.NE自動(dòng)維護(hù)。通過重寫LoadViewState方法組件,開發(fā)人員可控制如何還原視圖狀態(tài)以及如何將其內(nèi)容影射到內(nèi)部狀態(tài)。LoadViewState方法就是從ViewState中獲取上一次的狀態(tài),并按照頁(yè)面的控件樹的結(jié)構(gòu),用遞歸來遍歷整個(gè)樹,將對(duì)應(yīng)的狀態(tài)恢復(fù)到每一個(gè)控件上。
(3)處理回發(fā)數(shù)據(jù):還原了視圖狀態(tài),頁(yè)面樹種的各個(gè)控件的狀態(tài)就與瀏覽器上次呈現(xiàn)該頁(yè)面時(shí)這些控件所處的狀態(tài)相同。下一步需要更新這些控件的狀態(tài)以發(fā)送給客戶端。
回發(fā)數(shù)據(jù)處理階段是各個(gè)控件有機(jī)會(huì)更新其狀態(tài),以便準(zhǔn)確的反映相應(yīng)的HTML元素在客戶端的狀態(tài)。例如,一個(gè)服務(wù)器TextBox控件對(duì)應(yīng)的HTML元素是<input type=text>,在回發(fā)數(shù)據(jù)階段,TextBox控件將檢索<input>標(biāo)記的當(dāng)前值并用它刷新其內(nèi)部狀態(tài)。每個(gè)控件負(fù)責(zé)從以發(fā)送的數(shù)據(jù)中提取相應(yīng)值,并更新其某些屬性。TextBox控件將更新Text屬性,而CheckBox控件將刷新其Checked屬性。服務(wù)器控件和HTML元素之間的匹配關(guān)系由二者的ID確定。
頁(yè)框架將在每個(gè)提交數(shù)據(jù)的控件上實(shí)現(xiàn)IpostBackDataHandler接口,然后激發(fā)LoadPostData事件,通過頁(yè)面解析發(fā)現(xiàn)實(shí)現(xiàn)了IpostBackDataHandle接口的控件,這樣就能正確的回傳數(shù)據(jù)更新控件狀態(tài)。在識(shí)別控件時(shí),ASP.NET通過匹配控件的唯一標(biāo)示符來更新正確的控件,該標(biāo)識(shí)符具有名稱值集和中的名稱值對(duì)。這也就是在所有特定的頁(yè)中每個(gè)控件都需要一個(gè)唯一標(biāo)識(shí)符的原因之一。其他的步驟都由框架來完成,例如確定每個(gè)標(biāo)識(shí)符在環(huán)境中是否唯一以及控件的基本屬性等。
LostPostData方法的原型如下:
Public virtual bool LoadPostData(string postDatakey, NameValueCollection postCollection)
PostDataKey是標(biāo)識(shí)控件的關(guān)鍵字,可以理解為控件的ID,postCollection是包含回發(fā)數(shù)據(jù)的集合,可以理解為視圖狀態(tài)值。該方法返回一個(gè)bool值,如果是true,則表示控件狀態(tài)因回發(fā)而更改;否則返回false。頁(yè)框架會(huì)更跟蹤所有返回true的控件并在這些控件上調(diào)用RaisePostDataChangeEvent事件。
LoadPostData方法是由System..Web.WebControls.Control定義的,而添加的每一個(gè)服務(wù)器控件也是從System..Web.WebControls.Control繼承的,所以對(duì)于數(shù)據(jù)的回發(fā)處理并不需要干預(yù)。
(4)加載頁(yè)面Load:在回發(fā)數(shù)據(jù)處理階段結(jié)束時(shí),頁(yè)面中的所有控件都根據(jù)客戶端上所輸入的更改來更新的狀態(tài)。此時(shí),對(duì)頁(yè)面激發(fā)OnLoad事件。對(duì)于這個(gè)事件,相信大多數(shù)朋友都會(huì)比較熟悉,用Visual Studio.Net生成的頁(yè)面中的Page_Load方法就是響應(yīng)Load事件的方法,對(duì)于每一次請(qǐng)求,Load事件都會(huì)觸發(fā),Page_Load方法也就會(huì)執(zhí)行??梢岳迷摲椒▓?zhí)行一些頁(yè)面初始化,例如準(zhǔn)備好數(shù)據(jù)庫(kù)的連接字符串。在事件引用中,為了提高性能,通常使用Page類的IsPostBack屬性判斷是不是數(shù)據(jù)回發(fā)。
(5)回發(fā)更改通知RaisePostDataChanged:如(3)所述,在所有實(shí)現(xiàn)了IpostBackDataHandler接口的控件被正確的回傳數(shù)據(jù)更新后,每個(gè)控件都有一個(gè)布爾值的標(biāo)識(shí),標(biāo)識(shí)其自上一次提交后改控件的數(shù)據(jù)是被更改還是保持其值。然后ASP.NET通過搜索頁(yè)來尋找任何顯示控件數(shù)據(jù)被更改的標(biāo)識(shí)并激發(fā)RaisePostDataChanged。RaisePostDataChanged事件直到Load事件發(fā)生后,所有控件被更新后才激發(fā)。這保證了在控件被回傳數(shù)據(jù)更新前,其他控件的數(shù)據(jù)在RaisePostDataChanged事件中沒有被手動(dòng)更改過。雖然也可以在Page的基礎(chǔ)上自己定義數(shù)據(jù)更改的事件,但通常這個(gè)事件由太大用處。
(6)處理回發(fā)事件RaisePostBackEvent:當(dāng)回傳更新導(dǎo)致數(shù)據(jù)改變而引發(fā)服務(wù)器端事件后,引發(fā)回傳的對(duì)象會(huì)在RaisePostBackEvent事件中被處理。這種引發(fā)回傳的對(duì)象往往是一個(gè)按鈕被單擊或者其狀態(tài)改變而引發(fā)回傳的控件。例如Button觸發(fā)樂Onclick事件、客戶端修改了某個(gè)文本框的文本、同時(shí)將AutoPostBack設(shè)置為true、觸發(fā)TextChanged事件等。
很多代碼都在這個(gè)事件中執(zhí)行,因?yàn)檫@是控制事件驅(qū)動(dòng)邏輯的理想位置。為了保證呈現(xiàn)到瀏覽器的數(shù)據(jù)的正確性,在一系列的回傳事件后,RaisePostBackEvent事件最終被激發(fā)?;谝恢滦钥紤],會(huì)傳中改變的控件直到這個(gè)函數(shù)被執(zhí)行后才被更新。在實(shí)際的ASP.NET開發(fā)工作中要做的工作就是在此事件發(fā)生前處理代碼。
(7) 預(yù)呈現(xiàn)PreRender:在處理回發(fā)事件后,頁(yè)面就準(zhǔn)備進(jìn)行呈現(xiàn)。這一階段的標(biāo)志是PreRender事件。各個(gè)控件可利用這個(gè)很好的時(shí)機(jī),以便執(zhí)行任何需要在保存視圖狀態(tài)和呈現(xiàn)輸出結(jié)果的前一刻完成得最后一些更新操作。最終請(qǐng)求的處理都會(huì)轉(zhuǎn)變?yōu)榘l(fā)揮服務(wù)器的響應(yīng),預(yù)呈現(xiàn)這個(gè)階段就是執(zhí)行在最終呈現(xiàn)之前所做的狀態(tài)的更改,因?yàn)樵诔尸F(xiàn)一個(gè)控件之前,必須更具它的屬性來產(chǎn)生HTML,比如Style屬性。這是典型的例子,這預(yù)呈現(xiàn)之前,可以更改一個(gè)控件的Style,當(dāng)執(zhí)行預(yù)呈現(xiàn)時(shí),就可以把Style保存下來,做為呈現(xiàn)階段顯示HTML的樣式信息。
(8)保存狀態(tài)SaveViewState:下一個(gè)狀態(tài)為SaveViewState,在這一狀態(tài)中所有控件以及頁(yè)面本身可以刷新自己的SaveState集合的內(nèi)容。所得到的視圖狀態(tài)隨后得以序列化、進(jìn)行哈希運(yùn)算、進(jìn)行Base64編碼并關(guān)聯(lián)到VI-EMSTATE隱藏自端。
(9)呈現(xiàn)視圖Render:到這里,實(shí)際上頁(yè)面對(duì)請(qǐng)求的處理基本就告一段落了,在Render事件中,也調(diào)用對(duì)象是它們呈現(xiàn)為HTML,然后也收集HTML發(fā)送給客戶??蛻艚邮盏紿TML標(biāo)記后進(jìn)行重組,最終顯示給客戶。當(dāng)Render事件被重載時(shí),開發(fā)者可以為瀏覽器創(chuàng)建定值的HTML,此時(shí)頁(yè)面創(chuàng)建的任何HTML都還沒有生效。Render方法用HtmlTextWriter對(duì)象做參數(shù)并由它產(chǎn)生HTML送給瀏覽器。這主要用于自定義控件的開發(fā)。
(10)處置Disposed:執(zhí)行銷毀控件前的所有最終清理操作。在此階段必須釋放對(duì)昂貴資源的引用,如內(nèi)存的退出、數(shù)據(jù)庫(kù)的連接等。
(11)卸載Unload:一個(gè)頁(yè)面的最后生存標(biāo)志就是Unload事件,該事件在頁(yè)面對(duì)象被解除之前發(fā)生。在此事件中,可以調(diào)用Dispose方法盡可能釋放占用的任何關(guān)鍵資源(例如,文件、圖形對(duì)象以及數(shù)據(jù)庫(kù)連接)。
////////////////////////////////////////////////////////////////////////////////////////////////////////////
一個(gè)Page處理的過程講解
Page類的派生關(guān)系
Page是從TemplateControl中派生的,TemplateControl從Control派生。他們的定義分別如下:
//Control,從object派生,實(shí)現(xiàn)了四個(gè)接口
public class Control : System.ComponentModel.IComponent,
System.IDisposable,
System.Web.UI.IParserAccessor,
System.Web.UI.IDataBindingsAccessor
{  }
//TemplateControl從Control派生,實(shí)現(xiàn)了接口System.Web.UI.INamingContainer
public abstract class TemplateControl : Control, System.Web.UI.INamingContainer
{  }
//Page從TemplateControl派生,實(shí)現(xiàn)了接口System.Web.UI. IHttpHandler
public class Page : TemplateControl, System.Web.IHttpHandler
{  }
而你編寫的Page,你在_aspx.cs文件中編寫的類是從Page派生,這個(gè)繼承關(guān)系是你添加WebForm頁(yè)面時(shí),Visual Studio .net幫你建好的。而aspx的頁(yè)面在運(yùn)行時(shí)會(huì)被解釋為一個(gè)從_aspx.cs文件中的類的派生類。(這里需要補(bǔ)充資料)。
正 題
猜想
當(dāng)IIS接收到aspx頁(yè)面一個(gè)請(qǐng)求,交給aspnet_isapi.dll處理。aspnet_isapi然后做以下的事情:
MyPage __p;
__p = new MyPage();
__p.ProcessRequest(System.Web.HttpContext.Current)
以上是我個(gè)人的估計(jì),究竟事實(shí)是不是這樣,我會(huì)找Microsoft的工程師要答案!我在System.Web.dll中沒有找到處理產(chǎn)生Page實(shí)例的il,Page類的實(shí)例的創(chuàng)建可能是aspnet_isapi.dll作了,而aspnet_isapi.dll不是使用.net編寫的,其內(nèi)部的運(yùn)行究竟如何無從得知。
以下不是猜想!
ProcessRequest(HttpContext)方法
Page中的ProcessRequest(System.Web.HttpContext)方法是這樣的:
public virtual void ProcessRequest(Sunrise.Web.HttpContext context)
{
this.SetIntrinsics(context); //進(jìn)行最基本初始化
this.ProcessRequest(); //處理請(qǐng)求
}
SetIntrinsics方法
從上面的代碼可以看到,首先會(huì)調(diào)用SetIntrinsics(HttpContext context)方法,SetIntrinsics的作用是對(duì)Page的成員變量進(jìn)行基本的初始化。SetIntrinsics如下:
//進(jìn)行最基本初始化,設(shè)置_context、_request、_application、_cache的初值
private void  SetIntrinsics(HttpContext context)
{
this._context = context;
this._request =    context.Request;
this._response = context.Response;
this._application = context.Application;
this._cache = context.Cache;
if(this._clientTarget != null) {
if(this._clientTarget.Length >0)  {
this._request.ClientTarget = this._clientTarget;
}
}
//調(diào)TempalateControl的HookUpAutomaticHandlers()方法初始化基本事件
//包括:Init、Load、DataBinding、PreRender、Unload、Error、
//AbortTransaction、CommitTransaction
this.HookUpAutomaticHandlers();
}
ProcessRequest方法
然后就開始執(zhí)行ProcessRequest()方法,大致如下:
try
{
if(this.IsTransacted) //如果是事務(wù)狀態(tài)
{
this.ProcessRequestTransacted();
}
else //非事務(wù)狀態(tài)
{
this.ProcessRequestMain();
}
this.ProcessRequestEndTrace();
}
finally
{
//釋放資源,把_request、_response置為null,并執(zhí)行UnloadRecursive(true)
this.ProcessRequestCleanup();
}
ProcessRequestMain方法
通過上面的代碼可以知道,當(dāng)一個(gè)Page是非事務(wù)模式時(shí),響應(yīng)ProcessRequestMain()。事實(shí)上,是事務(wù)模式時(shí),也是調(diào)用ProcessRequestMain()。以下是關(guān)于ProcessRequestMain()方法的偽碼:
//step1 調(diào)用Control.InitRecursive()進(jìn)行遞歸初始化 Control的OnInit()方法將會(huì)在此時(shí)被調(diào)用
this.InitRecursive(null);
//如果是回傳狀態(tài)
if(this.IsPostBack)
{
//step2 裝載ViewState
///裝載Page的ViewState,Control的LoadViewState()方法將會(huì)在這里被調(diào)用
this.LoadPageViewState();
//step3 處理回傳的數(shù)據(jù),如果Control實(shí)現(xiàn)了System.Web.UI.IPostBackDataHandler,
//LoadPostData()方法在此時(shí)被調(diào)用
this.ProcessPostData(this._requestValueCollection, true);
}
//step4 調(diào)用Control.LoadRecursive()方法裝載SubControls
//Control的Load()方法在此時(shí)被調(diào)用
this.LoadRecursive();
//如果是回傳狀態(tài)
if(this.IsPostBack)
{
//step 5 再次處理未處理完的回傳數(shù)據(jù),
//注意第二次調(diào)用時(shí)第二個(gè)參數(shù)是false,而第一次是true
//第二次處理回傳數(shù)據(jù)的作用可能是用來處理在OnLoad中創(chuàng)建的Control的數(shù)據(jù),??
this.ProcessPostData(this._leftoverPostData, false);
//step6 響應(yīng)數(shù)據(jù)更改事件,
//如果Control實(shí)現(xiàn)了System.Web.UI.IPostBackDataHandler接口,
//Control的RaisePostDataChangedEvent()方法在此時(shí)被調(diào)用
this.RaiseChangedEvents();
//step7 響應(yīng)回傳事件 __dopostback()
//如果Control實(shí)現(xiàn)了System.Web.UI.IPostBackEventHandler接口,Control的RaisePostBackEvent()方法在此時(shí)執(zhí)行
this.RaisePostBackEvent(this._requestValueCollection);
//step8 調(diào)用Control的PreRenderRecursiveInternal()方法,
//Control的OnPreRender()方法在此時(shí)被調(diào)用
this.PreRenderRecursiveInternal();
}
//step9 BuiltTree 構(gòu)建ViewState,
//ViewState使用通過LosFormatter對(duì)ViewState進(jìn)行編碼,保存在Trace中
this.BuildProfileTree("ROOT",this.EnableViewState);
//step10 保存Page的ViewState
//Control的SaveViewState()方法
this.SavePageViewState();
//step11 輸出
//Control的Render()方法在此時(shí)被調(diào)用
this.RenderControl(this.CreateHtmlTextWriter(this.Response.Output));
ProcessRequestMain方法圖示
Init
Load ViewState
Load PostData
Load
Load PostData
RaiseChangeEvents
RaisePostBackEvents
BuildProfileTree    (viewstate 編碼)
SaveViewState
Render
Dispose
Unload
此時(shí)產(chǎn)生HTML代碼
OnInit()方法被調(diào)用
OnLoad()方法被調(diào)用
處理回傳數(shù)據(jù)
再次處理回傳數(shù)據(jù)
響應(yīng)數(shù)據(jù)修改事件,如TextBox的TextChagned
響應(yīng)回傳事件,客戶端的__dopostback
ProcessRequestTransacted方法
事實(shí)上,在事務(wù)狀態(tài)下,也是調(diào)用ProcessRequestMain()的,我們來看一下ProcessRequestTransacted的代碼:
bool V_0;
System.Web.Util.TransactedCallback V_1;
V_0 = false;
//創(chuàng)建事務(wù)回調(diào)的delegate
V_1 = new System.Web.Util.TransactedCallback(this.ProcessRequestMain);
//在事務(wù)環(huán)境下調(diào)用ProcessRequestMain()
System.Web.Util.Transactions.InvokeTransacted(
V_1,
(System.EnterpriseServices.TransactionOption)(this._transactionMode),
ref V_0
);
if(V_0) {
this.OnAbortTransaction(System.EventArgs.Empty); //終止事務(wù)
}
Else {
this.OnCommitTransaction(System.EventArgs.Empty); //提交事務(wù)
}
InitRecursive方法
在ProcessRequestMain 方法中,首先執(zhí)行Control的InitRecursive方法。在InitRecursive中,OnInit方法被執(zhí)行。具體如下:
internal void InitRecursive(System.Web.UI.Control namingContainer) //ok
{
string V_0;
int V_1;
int V_2;
System.Web.UI.Control V_3;
if(this._controls != null)
{
//flag[128]表示是否實(shí)現(xiàn)了System.Web.UI.INamingContainer接口
if(this.flags[128]) {
namingContainer = this;
}
//設(shè)置_controls為只讀,并返回原來的_readOnlyErrorMsg,保存在V_0
V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");
V_1 = this._controls.Count;
for(V_2 = 0;V_2 < V_1; V_2++)
{
V_3 = this._controls[V_2];
V_3._namingContainer = namingContainer;
if(namingContainer != null)
{
if((V_3._id == null) && (!(V_3.flags[64])) )
{
this.GenerateAutomaticID();
}
}
V_3._page = this._page;
V_3.InitRecursive(namingContainer);
}
//回復(fù)_controls原來的狀態(tài)
this._controls.SetCollectionReadOnly(V_0);
this._controlState = Sunrise.Web.UI.ControlState.Initialized;
//OnInit方法在此時(shí)被調(diào)用
this.OnInit(System.EventArgs.Empty);
this.TrackViewState();
}
}
LoadPageViewState方法
在ProcessRequestMain 方法中,執(zhí)行InitRecursive方法進(jìn)行初始化后,如果Page的IsPostBack屬性值為True,則會(huì)接著執(zhí)行LoadPageViewState方法。
LoadPageViewState應(yīng)該結(jié)合來SavePageViewState來看,這樣更容易理解。具體如下:
internal void LoadPageViewState()
{
System.Web.UI.Triplet V_0;
string V_1;
//獲得使用LosFormater反序列化(Deserialize)得到的對(duì)象
V_0 = (System.Web.UI.Triplet)this.LoadPageStateFromPersistenceMedium();
if(V_0 != null)
{
V_1 = (string)V_0.First;
int.Parse(V_1,System.Globalization.NumberFormatInfo.InvariantInfo);
this.GetTypeHashCode();
//判斷V_1和Page調(diào)用GetTypeHashCode()方法獲得的值是否相等,
//并把比較結(jié)果保存在_fPageLayoutChanged ??
this._fPageLayoutChanged = (int.Parse(V_1,System.Globalization.NumberFormatInfo.InvariantInfo) != this.GetTypeHashCode());
if(!(this._fPageLayoutChanged))
{
//調(diào)用Control.LoadViewStateRecursive()方法,
//遞歸裝載ViewState,
//Control的LoadViewState()方法將會(huì)在這里被執(zhí)行
this.LoadViewStateRecursive(V_0.Second);
this._controlsRequiringPostBack = (System.Collections.ArrayList)V_0.Third;
}
}
}
LoadViewStateRecursive方法
通過觀察LoadPageViewState的代碼可以得知,LoadPageViewState中執(zhí)行LoadViewStateRecursive來進(jìn)行Control的LoadViewState過程。
LoadViewStateRecursive的過程大致是這樣,把參數(shù)savedState轉(zhuǎn)換為Triplet對(duì)象,使用Triplet對(duì)象的First做參數(shù)來執(zhí)行LoadView方法,然后使用Triplet對(duì)象的Second和Third對(duì)Controls進(jìn)行LoadViewStateRecursive。
這個(gè)方法應(yīng)該參照SaveViewStateRecursive一起閱讀,這樣更方便理解。如下:
internal void LoadViewStateRecursive(object savedState)
{
System.Web.UI.Triplet V_0;
System.Collections.ArrayList V_1;
System.Collections.ArrayList V_2;
Sunrise.Web.UI.ControlCollection V_3;
int V_4;
int V_5;
int V_6;
int V_7;
//如果參數(shù)為null或EnableViewState為False
if((savedState == null) || (this.flags[4]) ))
//flags[4]表示EnableViewState: true時(shí),EnableViewState為false,false時(shí)EnableViewState為true
{         return;     }
//轉(zhuǎn)換為Triplet對(duì)象,Triplet有三個(gè)public的Fields:First、Second、Third,使用Triplet表示使代碼更直觀,而且更快
V_0 = (System.Web.UI.Triplet)savedState;
//如果control的Page不為null,而且this.Page.IsPostBack為True,執(zhí)行LoadViewState方法
if((this.Page != null) && (this.Page.IsPostBack) )
{         this.LoadViewState(V_0.First);     }
//對(duì)this.Controls中的Control進(jìn)行LoadViewState
if(V_0.Second != null)
{
V_1 = (System.Collections.ArrayList)V_0.Second; //kes
V_2 = (System.Collections.ArrayList)V_0.Third; //values
V_3 = this.Controls;
V_4 = V_3.Count;
V_5 = V_1.Count;
for(V_6=0; V_6 < V_5; V_6 ++)
{
V_7 = (int)V_1[V_6];
if(V_7 < V_4)
{                   V_3[V_7].LoadViewStateRecursive(V_2[V_6]);              }
else
{
if(this._controlsViewState == null)
{
this._controlsViewState = new System.Collections.Hashtable();
}
this._controlsViewState[V_7] = V_2[V_6];
}
}
}
//將_controlState設(shè)置為ViewStateLoaded
this._controlState = Sunrise.Web.UI.ControlState.ViewStateLoaded;
}
LoadViewState方法
LoadViewState方法的是Protected,當(dāng)你構(gòu)建自己的Control時(shí),可以重載它。此時(shí)你應(yīng)該在你寫的LoadViewState方法里執(zhí)行base. LoadViewState(something)。Control的LoadViewState代碼如下:
protected virtual void  LoadViewState(object savedState)
{
object V_0;
if(savedState != null)
{
this.ViewState.LoadViewState(savedState);
V_0 = this.ViewState["Visible"];
if(V_0 != null)
{
// flags[16]表示Visible,false時(shí),Visible為true,值為false時(shí),Visible為true
this.flags[16] = (!((bool)V_0));
this.flags[32] = true; // flags[32]表示是否已經(jīng)LoadView ??
}
}
}
ProcessPostData方法
當(dāng)ProcessRequestMain執(zhí)行了LoadPageViewState方法后,接著就是ProcessPostData,這個(gè)方法是用來處理回傳數(shù)據(jù)。這個(gè)方法被執(zhí)行兩遍,分別在LoadRecursive之前和之后個(gè)執(zhí)行一遍。第一次執(zhí)行時(shí),參數(shù)fBeforeLoad值為True,第二次為False。
//處理回傳的數(shù)據(jù)
//當(dāng)fBeforeLoad為true時(shí),是第一次調(diào)用,fBeforeLoad為false時(shí),為第二次調(diào)用
private void ProcessPostData(System.Collections.Specialized.NameValueCollection postData, bool fBeforeLoad) //ok
{
string V_0;
Sunrise.Web.UI.Control V_1;
System.Web.UI.IPostBackDataHandler V_2;
bool V_3;
System.Collections.ArrayList V_4;
string V_5;
System.Web.UI.IPostBackDataHandler V_6;
bool V_7;
System.Collections.IEnumerator V_8;
System.IDisposable V_9;
if(this._changedPostDataConsumers == null)
{
this._changedPostDataConsumers = new System.Collections.ArrayList();
}
if(postData != null)
{
V_8 = postData.GetEnumerator();
try
{
while(V_8.MoveNext())
{
V_0 = (string)V_8.Current;
if(V_0 != null)
{
//判斷回傳數(shù)據(jù)是否在系統(tǒng)PostFields內(nèi),
//s_systemPostFields包括__EVENTTARGET、__EVENTARGUMENT、__VIEWSTATE
if(!s_systemPostFields.Contains(V_0))
{
V_1 = this.FindControl(V_0); //在Page中查找匹配的Control
if((V_1 == null) //如果找不到,將數(shù)據(jù)保存在_leftoverPostData中
&& (fBeforeLoad) )
{
if(this._leftoverPostData == null)
{
this._leftoverPostData = new System.Collections.Specialized.NameValueCollection();
}
this._leftoverPostData.Add(V_0,null);
}
else //如果找到了……
{
//如果找到的結(jié)果實(shí)現(xiàn)了System.Web.UI.IPostBackDataHandler接口,
//調(diào)用RegisterRequiresRaiseEvent方法
//賦值給_registeredControlThatRequireRaiseEvent
if(!(V_1 is System.Web.UI.IPostBackDataHandler))
{
if(V_1 is System.Web.UI.IPostBackEventHandler)
{
this.RegisterRequiresRaiseEvent(
(System.Web.UI.IPostBackEventHandler)V_1
);
}
}
else//如果找到的結(jié)果沒有實(shí)現(xiàn)System.Web.UI.IPostBackDataHandler接口
{
V_2 = (System.Web.UI.IPostBackDataHandler)V_1;
V_3 = V_2.LoadPostData(V_0,this._requestValueCollection); //V_2裝載回傳數(shù)據(jù)
if(V_3) //如果V_2裝載回傳數(shù)據(jù)時(shí)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)被修改,將登記V_2在_changedPostDataConsumers中
{
this._changedPostDataConsumers.Add(V_2);
}
//在_controlsRequiringPostBack中移去V_0
//_controlsRequiringPostBack的值在LoadPageViewState()方法中被賦值
if(this._controlsRequiringPostBack != null)
{
this._controlsRequiringPostBack.Remove(V_0);
}
}
}
}
}
}
}
finally
{
V_9 = V_8 as System.IDisposable;
if(V_9 != null)
{
V_9.Dispose();
}
}
}
V_4 = null;
//處理_controlsRequiringPostBack中剩下的數(shù)據(jù)項(xiàng)
if(this._controlsRequiringPostBack != null)
{
V_8 = this._controlsRequiringPostBack.GetEnumerator();
try
{
while(V_8.MoveNext())
{
V_5 = (string)V_8.Current;
V_6 = (System.Web.UI.IPostBackDataHandler)this.FindControl(V_5);
if(V_6 != null)
{
//V_7裝載回傳數(shù)據(jù)
V_7 = V_6.LoadPostData(V_5,this._requestValueCollection);
//如果V_6裝載回傳數(shù)據(jù)時(shí)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)被修改,
//將登記V_6在_changedPostDataConsumers中
if(V_7) {
this._changedPostDataConsumers.Add(V_6);
}
}
else
{
if(fBeforeLoad) //如果是第一次調(diào)用,保留
{
if(V_4 == null)
{
V_4 = new System.Collections.ArrayList();
}
V_4.Add(V_5);
}
}
}
}
finally
{
V_9 = V_8 as System.IDisposable;
if(V_9 != null)
{
V_9.Dispose();
}
}
}
//如果是第一次調(diào)用,值為未處理的數(shù)據(jù)項(xiàng),第二次調(diào)用值為null
this._controlsRequiringPostBack = V_4;
}
LoadRecursive方法
LoadRecursive方法的過程大致是這樣,先執(zhí)行Load方法,然后對(duì)Controls執(zhí)行LoadRecursive。
代碼如下:
internal void LoadRecursive()
{   string V_0;
int V_1;
int V_2;
//在這里執(zhí)行OnLoad方法
this.OnLoad(System.EventArgs.Empty);
if(this._controls != null)
{
//設(shè)置_controls為只讀
V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");
V_1 = this._controls.Count;
for(V_2 = 0;V_2 < V_1; V_2++)
{       this._controls[V_2].LoadRecursive();        }
//回復(fù)原來的狀態(tài)
this._controls.SetCollectionReadOnly(V_0);
}
this._controlState = Sunrise.Web.UI.ControlState.Loaded;
}
RaiseChangedEvents方法
如果Control實(shí)現(xiàn)了System.Web.UI.IPostBackDataHandler接口,Control的RaisePostDataChangedEvent將會(huì)在這里被調(diào)用。需要的響應(yīng)的RaisePostDataChangedEvent的典型例子是TextBox。TextBox的Text數(shù)據(jù)在客戶端可能被修改,如果修改了,需要獲得通知,以響應(yīng)TextChanged事件。
internal void RaiseChangedEvents() //ok
{
int V_0;
System.Web.UI.IPostBackDataHandler V_1;
Sunrise.Web.UI.Control V_2;
if(this._changedPostDataConsumers != null)
{
for(V_0=0; V_0 < this._changedPostDataConsumers.Count; V_0++)
{
V_1 = (System.Web.UI.IPostBackDataHandler)this._changedPostDataConsumers[V_0];
V_2 = V_1 as Sunrise.Web.UI.Control;
//如果V_2是Page的SubControls,調(diào)用RaisePostDataChangedEvent()
if((V_2 != null) || (V_2.IsDescendentOf(this)))
{     V_1.RaisePostDataChangedEvent();       }
}
}
}
RaisePostBackEvent方法
當(dāng)執(zhí)行Client端JavaScript的__dopostback()函數(shù)時(shí),將產(chǎn)生回傳事件。(此處需要補(bǔ)充資料)?;貍魇录脑硎?,Page產(chǎn)生的HTML代碼中,會(huì)產(chǎn)生兩個(gè)隱藏域(Hidden),__EVENTTARGET和__ EVENTARGUMENT,不同的Control產(chǎn)生執(zhí)行__dopostback()的方法不一致。調(diào)用的時(shí)候大多數(shù)是這樣:
<input type=hidden name=__EVENTTARGET>
<input type=hidden name=__ EVENTARGUMENT>
__dopostback(control_uniqueid, ‘’);
當(dāng)Form提交的時(shí)候,RaisePostBackEvent中根據(jù)control_uniqueid來找到需要響應(yīng)事件的Server Control。__ EVENTARGUMENT是事件的參數(shù),參數(shù)在開發(fā)簡(jiǎn)單的Server Control通常是不需要,在復(fù)雜的Server Control時(shí)才用。
例如System.Web.UI.WebControls.LinkButton。
private void RaisePostBackEvent(System.Collections.Specialized.NameValueCollection postData)
{
string V_0;
Sunrise.Web.UI.Control V_1;
string V_2;
if(this._registeredControlThatRequireRaiseEvent != null)
{
this.RaisePostBackEvent(_registeredControlThatRequireRaiseEvent, null);
return;
}
V_0 = postData["__EVENTTARGET"];
if((V_0 != null) && (V_0.Length >0))
{
V_1 = this.FindControl(V_0);
if((V_1 != null) && (V_1 is System.Web.UI.IPostBackEventHandler) )
{
V_2 = postData["__EVENTARGUMENT"];
this.RaisePostBackEvent((System.Web.UI.IPostBackEventHandler)V_1, V_2);
}
} else  {
this.Validate();
}
}
PreRenderRecursiveInternal方法
Control的PrenRender方法會(huì)在這里被執(zhí)行。代碼如下:
internal void PreRenderRecursiveInternal()
{
string V_0;
int V_1;
int V_2;
// flags[16]表示Visible,值為true時(shí),Visible為false,值為false時(shí),Visible為true
if(!(this.flags[16]))
{
this.EnsureChildControls();
//OnPreRender在這里被執(zhí)行
this.OnPreRender(System.EventArgs.Empty);
if(this._controls != null)
{
//設(shè)置只讀
V_0 = this._controls.SetCollectionReadOnly("Parent_collections_readonly");
V_1 = this._controls.Count;
for(V_2 = 0;V_2 < V_1; V_2++)
{ this._controls[V_2].PreRenderRecursiveInternal(); }
//回復(fù)原來的狀態(tài)
this._controls.SetCollectionReadOnly(V_0);
}
}
this._controlState = Sunrise.Web.UI.ControlState.PreRendered;
}
BuildProfileTree 方法
構(gòu)建ViewState的存放空間,放在Trace里。(此處需要更詳細(xì)的說明)
protected void BuildProfileTree(string parentId, bool calcViewState)
{
int V_0;
int V_1;
int V_2;
calcViewState = calcViewState || (!(this.flags[4]));
if(calcViewState)
{
//計(jì)算LosFormatter會(huì)產(chǎn)生編碼結(jié)果的長(zhǎng)度
V_0 = Sunrise.Web.UI.LosFormatter.EstimateSize(this.SaveViewState());
}  else   {
V_0 = 0;
}
this.Page.Trace.AddNewControl(
this.UniqueID,
parentId,
this.GetType().FullName,
V_0
);
if(this._controls != null)
{
V_1 = this._controls.Count;
for(V_2 =0; V_2 < V_1; V_2 ++)
{ this._controls[V_2].BuildProfileTree(this.UniqueID, calcViewState); }
}
}
SavePageViewState 方法
保存Page的ViewState,LosFormatter的編碼結(jié)果放置于_viewStateToPersist中。此方法應(yīng)該結(jié)合LoadPageViewState一起來分析。
使用Triplet和Pair保存ViewState時(shí)常用的技巧。這里使用了Triplet。
(需要補(bǔ)充關(guān)于LosFormatter的說明)
SavePageViewState和SavePageStateToPersistenceMedium的代碼如下:
internal void SavePageViewState()
{
System.Web.UI.Triplet V_0;
int V_1;
if(!(this._needToPersistViewState))
{  return;   }
V_0 = new System.Web.UI.Triplet();
V_1 = this.GetTypeHashCode();
//將數(shù)字轉(zhuǎn)換為字符
V_0.First = V_1.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
//_registeredControlsThatRequirePostBack是一個(gè)ArrayList,
//其內(nèi)容項(xiàng) RegisterRequiresPostBack(System.Web.UI.Control control)來添加
V_0.Third = this._registeredControlsThatRequirePostBack;
if(this.Context.TraceIsEnabled)
{
this.Trace.AddControlViewstateSize(
this.UniqueID,
Sunrise.Web.UI.LosFormatter.EstimateSize(V_0)
);
}
//執(zhí)行SaveViewStateRecursive()方法,把返回結(jié)果保存賦給V_0.Second。
V_0.Second = this.SaveViewStateRecursive();
this.SavePageStateToPersistenceMedium(V_0);
}
protected virtual void SavePageStateToPersistenceMedium(object viewState)
{
this._viewStateToPersist = viewState;
}
SaveViewStateRecursive方法
在SavePageViewState方法中執(zhí)行SaveViewStateRecursive方法來獲取ControlTree的SaveViewState的結(jié)果。
internal object SaveViewStateRecursive()
{
object V_0;
System.Collections.ArrayList V_1;
System.Collections.ArrayList V_2;
int V_3;
int V_4;
Sunrise.Web.UI.Control V_5;
object V_6;
System.Web.UI.Triplet V_7;
if(this.flags[4])
{   return(null);   }
//獲得Control本身的SaveViewState()結(jié)果
V_0 = this.SaveViewState();
V_1 = null;
V_2 = null;
//獲取SubControls的SaveViewStateRecursive()結(jié)果
if(this._controls != null)
{
V_3 = this._controls.Count;
for(V_4=0; V_4<V_3; V_4++)
{
V_5 = this._controls[V_4];
V_6 = V_5.SaveViewStateRecursive();
if(V_6 != null)
{
if(V_1 == null)
{
V_1 = new System.Collections.ArrayList();
V_2 = new System.Collections.ArrayList();
V_1.Add(V_4);
V_2.Add(V_6);
}
}
}
}
V_7 = null;
//如果Control本身的SaveViewState()結(jié)果不為null,
//而且SuControls的SaveViewStateRecursive()結(jié)果不為null
if((V_0 != null) || (V_1 != null) )
{
V_7 = new System.Web.UI.Triplet(V_0, V_1, V_2);
}
return(V_7);
}
RenderControl方法
ProcessRequestMain()執(zhí)行了PreRenderRecursive后,接著就執(zhí)行RenderControl方法。RenderControl是在Control中定義的方法。RenderControl是執(zhí)行Control的Render方法,輸出html文本。
public void  RenderControl(System.Web.UI.HtmlTextWriter writer) //ok
{
System.Web.HttpContext V_0;
int V_1;
int V_2;
// flags[16]表示Visible,true時(shí),Visible為false,值為false時(shí),Visible為true
if(!(this.flags[16]))
{
//如果this._page不為null,……
V_0 = (this._page == null) ? null: this._page._context;
if(V_0 != null)
{
if(V_0.TraceIsEnabled)
{
V_1 =V_0.Response.GetBufferedLength();
//Render方法在這里被執(zhí)行
this.Render(writer);
V_2 = V_0.Response.GetBufferedLength();
V_0.Trace.AddControlSize(this.UniqueID, V_2 - V_1);
}
}
else
{   //Render方法在這里被執(zhí)行
this.Render(writer);
}
}
}
Render和RenderChildren
Render和RenderChildren都可以被重載。在System.Web.UI.WebControls命名空間里,大部分Control都是從System.Web.UI.WebControls.WebControl中派生的,WebControl重載Render方法,分拆成三個(gè)方法,RenderBeginTage、RenderContent和RenderEndTag。如果Cotnrol是從WebControl中派生,通常只需要重載RenderContent。
下面是Control中的代碼:
protected virtual void Render(System.Web.UI.HtmlTextWriter writer)
{    this.RenderChildren(writer); }
protected virtual void RenderChildren(System.Web.UI.HtmlTextWriter writer) //ok
{   int V_0;
int V_1;
if(this._renderMethod != null)
{   this._renderMethod(writer,this);     }
else
{
if(this._controls != null)
{
V_0 = this._controls.Count;
for(V_1=0; V_1<V_0; V_1 ++)
{
this._controls[V_1].RenderControl(writer);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
在以前寫個(gè)一篇關(guān)于ASP.NET頁(yè)面生命周期的草稿,最近又看了看ASP.NET,做個(gè)補(bǔ)充,看看頁(yè)面初始過程到底是怎么樣的
下面是ASP.NET頁(yè)面初始的過程:
1. Page_Init();
2. Load ViewState;
3. Load Postback data;
4. Page_Load();
5. Handle control events;
6. Page_PreRender();
7. Page_Render();
8. Unload event;
9. Dispose method called;
下面對(duì)其中的一些過程作下描述:
1. Page_Init();
這個(gè)過程主要是初始化控件,每次頁(yè)面載入執(zhí)行這個(gè)初始過程,包括第一次和以后的Postback(這里說下Postback,其實(shí)就可以簡(jiǎn)單理解成用戶點(diǎn)擊SUBMIT按鈕之類的,把表單<Form>提交給服務(wù)器,這就是一次postback),在這里面可以訪問控件,但是這里面的控件值不是我們期待的控件里面的值,他只是一個(gè)控件的初始值(默認(rèn)值),舉例: 比如一個(gè)TextBox1,我們填入了"哈哈",在點(diǎn)擊SUBMIT提交了頁(yè)面后,在Page_Init()里面,我們?cè)L問到的TextBox1.Text不是我們的"哈哈",而是開始的""空字符串,如果TextBox1在我們?cè)O(shè)計(jì)的時(shí)候提供了默認(rèn)值,這里訪問到的也就是提供的默認(rèn)值,為什么呢,這就要看下一個(gè)過程了.
對(duì)應(yīng)的事件Page.Init
2. Load ViewState
這個(gè)過程是載入VIEWSTATE和Postback數(shù)據(jù),比如我們上面的TextBox1,這時(shí)就賦了"哈哈",所以,在Post_Init()對(duì)控件賦值是無意義的,它都會(huì)在這個(gè)過程里被改寫,當(dāng)然第一次頁(yè)面載入例外,因?yàn)闆]有VIEWSTATE數(shù)據(jù)。
沒有對(duì)應(yīng)的事件
3.Load Postback data;
上面說了,Postback可以理解成用戶提交表單數(shù)據(jù),所以這里就是處理表單數(shù)據(jù),當(dāng)然這里要設(shè)計(jì)到控件的設(shè)計(jì),一般情況不會(huì)要我們自己處理這個(gè)過程,我們暫且略過. (在以前那篇關(guān)于ASP.NET頁(yè)面生命周期的簡(jiǎn)單描述中,把這個(gè)過程和Load ViewState放在了一起,其實(shí)那是微軟提供的生命周期過程,這里單獨(dú)提出來是為了讓大家明白這是一個(gè)單獨(dú)的過程)
沒有對(duì)應(yīng)的事件
4. Page_Load();
這個(gè)過程也是每次頁(yè)面載入時(shí)一定會(huì)執(zhí)行的,但是注意和Page_Init的區(qū)別,上面已經(jīng)涉及了,這里注意的是一般都會(huì)用到Page.IsPostBack,該值指示該頁(yè)是否正為響應(yīng)客戶端回發(fā)而加載,或者它是否正被首次加載和訪問。
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{    //第一次執(zhí)行的CODE HERE  }
else
{    //用戶提交FORM(即Postback)CODE HERE  }
//每次這里的都回執(zhí)行CODE HERE
}
對(duì)應(yīng)的事件Page.Load
5. Handle control events;
這個(gè)過程里,相應(yīng)具體的控件事件,比如private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e)事件等等
沒有對(duì)應(yīng)的事件(我們自己的事件函數(shù)都包括在這個(gè)過程里比如上面的ListBox1_SelectedIndexChanged)
6. Page_
預(yù)先呈遞對(duì)象,這里是在向用戶程序呈現(xiàn)數(shù)據(jù)的倒數(shù)第二步,我估計(jì)提供這個(gè)過程的意義,也就是在這里能對(duì)控件屬性等等要呈現(xiàn)給用戶的數(shù)據(jù)進(jìn)行修改,這也是最后的修改,以前的修改(比如在Page_Init里面)都可能被覆蓋.做完這了還會(huì)進(jìn)行一個(gè)操作就是保存狀態(tài),即SaveViewState.
對(duì)應(yīng)的事件時(shí)Page.PreRender
7. Page_Render();
大家可以在瀏纜器里View->Source查看到,每個(gè)頁(yè)面都有一個(gè)隱藏的<input>,這里面的"__VIEWSTATE"就是我們服務(wù)器寫回來的頁(yè)面狀態(tài)信息,在這個(gè)之前,服務(wù)器要呈現(xiàn)頁(yè)面(也就是構(gòu)造HTML格式的文件),就是從這個(gè)"__VIEWSTATE"里面獲取的數(shù)據(jù),當(dāng)然大家也注意到了,這里有個(gè)Page.Render事件,我們可以添加自己的處理代碼,也就是說我們又可以更改數(shù)據(jù),不過這里推薦不要在這里修改,既然提供了PreRender,就應(yīng)該在里面做最后的修改,當(dāng)然這不是必須的,只是推薦!
對(duì)應(yīng)的事件Page.Render
8. Unload event;
大家應(yīng)該明白,當(dāng)想服務(wù)器請(qǐng)求一個(gè)對(duì)象的時(shí)候,就會(huì)在內(nèi)存里生成一個(gè)繼承頁(yè)面對(duì)象,也就是頁(yè)面的類,它繼承自System.Web.UI.Page.
當(dāng)頁(yè)面對(duì)象從內(nèi)存中卸載時(shí)發(fā)生,將觸發(fā)該事件.
對(duì)應(yīng)的事件Page.Unload
9. Dispose method called;
銷毀所有的對(duì)象.當(dāng)從內(nèi)存釋放Page時(shí)發(fā)生,這是生存期的最后階段。可能第8和9似乎有些模糊,不過我也沒怎么搞清楚,待研究!
對(duì)應(yīng)的事件Dispose
以上就是ASP.NET頁(yè)面周期的描述。
注意上面灰色背景的文字,如果一個(gè)過程中有對(duì)應(yīng)的事件,我們可以自己定義一個(gè)函數(shù)(當(dāng)然先在MSDN中找到函數(shù)原型),然后在
InitializeComponent中向事件的鏈表上添加上去,像下面:
private void InitializeComponent()
{
this.Unload += new System.EventHandler(this.MainWebForm_Unload);
this.Load += new System.EventHandler(this.Page_Load);
this.Init += new System.EventHandler(this.Page_Init);
this.PreRender += new System.EventHandler(this.My_PreRender);
}
對(duì)于幾個(gè)沒有對(duì)應(yīng)事件的過程,比如2.Load ViewState,我們可以重載Page的虛函數(shù)protected override void LoadViewState(object savedState);來添加自己的控制代碼,不過切忌掉用基類的對(duì)應(yīng)方法,比如:
protected override void LoadViewState(object savedState)
{
//自己處理VIEWSTATE
base.LoadViewState (savedState);
}
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ASP.Net請(qǐng)求處理機(jī)制初步探索之旅
ASP.NET2.0服務(wù)器控件之自定義狀態(tài)管理
aspx頁(yè)面事件執(zhí)行順序
壓縮ASP.NET中的ViewState的改進(jìn)方法
asp.net 頁(yè)面生命周期(Page lifeCycle) - grgufo的專欄 - ...
關(guān)于c#動(dòng)態(tài)添加文本框及下拉框
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服