asp.net 頁面 生命週期

ForTechnology發表於2012-09-08

大家在平時學習Asp.Net進行web開發時,為了滿足專案需要,將開發大量滿足需求的自定義控制元件。那關於自定義控制元件生命週期如何呢,與頁面生命週期有何區別呢?我今天跟大家詳細解釋一下:控制元件生命週期大概有11個階段,對於特殊的頁面(其實也是一種控制元件System.Web.UI.Page)的生命週期有更詳細的階段,比如對於每一種控制元件來說,都只有一個Init事件,但是Page對同一個事件卻分成了PreInit, Init, InitComplete三個階段。其具體的職責如下:

PreInit: 完成模板頁和主題的設定,只有這一次機會,一旦到了Init階段將不能更改。

Init: 依次觸發子控制元件的Init事件,進而執行對應的OnInit方法,完成子控制元件的初始化和設定命名容器。

InitComplete: 使控制元件具體檢視跟蹤能力。

下面具體說明控制元件生命週期的11階段:

1.初始化(對應OnInit方法)

      完成控制元件的初始化並通過ProcessRequest方法遞迴遍歷所有的子控制元件以及依次呼叫它們的OnInit方法。可以通過重寫OnInit方法來擴充套件 功能或增加初始化內容。除此之外,本階段將開啟控制元件的檢視跟蹤功能(呼叫TraceViewState方法),這樣才能在頁面回發時正確恢復控制元件的屬性。

2.載入檢視狀態(對應LoadViewState方法)

     本階段僅在頁面回發時才執行,事實上,在第一次訪問頁面時還沒有獲取到儲存在檢視狀態中的資料。本階段完成載入檢視狀態到控制元件(前提是該控制元件啟用檢視狀 態),對於複雜物件則需要重寫LoadViewState方法和SaveViewState方法。在每一次客戶端請求過程中,檢視狀態儲存在隱藏控制元件中, 每次請求都會將ViewState回傳到伺服器,以便在伺服器回傳資料以及判斷是否執行相應的回發事件。

3.載入回傳資料(對應LoadPostData方法)

      本階段僅在頁面回發時才執行,LoadPostData是實現介面IPostBackDataHandler的一個方法(主要實現控制元件資料回傳)。該方法 有一個引數NameValueCollection型別物件,裝載了客戶端提交的資料。根據控制元件舊值和新值比較是否一致,決定是否執行下面的 RaisePostDataChangedEvent方法。具體過程如下:客戶端修改窗體的資料提交後,接受的資料以“&”符號隔開的一些鍵值 對,頁面處理器根據傳遞的資料控制元件集合,根據匹配ID對應的伺服器控制元件是否實現IPostBackDataHandler介面,如實現此介面則呼叫控制元件的 LoadPostData方法以重新整理其值,否則不呼叫。

4.裝載(對應OnLoad方法)

      注意,頁面裝載時先執行頁面的Page_Load事件再依次遞迴執行各個子控制元件的OnLoad方法。本階段控制元件樹結構中的所有控制元件已經建立並完成初始化, 且狀態已還原和回傳給客戶端,可以重寫OnLoad方法完成一些所有請求共有的操作,還可以通過IsPostBack判斷控制元件是在第一次請求頁面還是回發 頁面時執行自定義初始化程式碼邏輯。

5.資料回傳事件通知(對應RaisePostDataChangedEvent方法)

      本階段僅在頁面回發時才執行,RaisePostDataChangedEvent是實現介面IPostBackDataHandler的一個方法(主要 實現控制元件資料回傳事件)。與LoadPostData匹配使用,當前者返回true時,才呼叫RaisePostDataChangedEvent方法。

6.觸發回發事件(對應RaisePostBackEvent方法)

      本階段僅在頁面回發時才執行,主要處理引起回發的客戶端事件,成功捕獲回發的客戶端事件進行服務端的相應處理。前提是實現IPostBackEventHandler介面。可以判斷是哪個控制元件引發的回發事件,從而進行不同的事件處理。

7.預呈現(對應OnPreRender方法)

      本階段主要完成控制元件呈現(Render)之前的一些工作,一般自定義控制元件都會重寫方法,對資源進行註冊(Javascript和隱藏域)。

8.儲存檢視狀態(對應SaveViewState方法)

       與LoadViewState過程正好相反,SaveViewState用於儲存頁面檢視狀態資訊。SaveViewState在第一次頁面請求時就會執行,而LoadViewState僅在頁面回發時執行。

9.呈現(對應Render方法)

       本階段主要完成控制元件標記和字元文字輸出到伺服器控制元件的輸出流中。可以直接寫Html,也可呼叫控制元件的RenderControl輸出到流中。

10.解除安裝(對應OnUnload方法)

       本階段將清除頁面的資源。OnUnload僅是一個控制元件生命週期內的事件,如果認為該方法會在離開頁面時或點選關閉按鈕時觸發是不正確的,因為頁面兩次請求是無狀態的,而因為Asp.Net檢視狀態機制看起來好像連續的。

11.釋放(對應Dispose方法)

        本階段將釋放資源(資料庫連線,IO檔案等)。

瞭解了嗎?如果理解了,我將這個過程用程式碼的形式描述出來,希望能有一個更加直觀的認識。

[DefaultProperty("Text")]
[ToolboxData("{0}:ControlLifeCycle>")]
public class ControlLifeCycle : WebControl, IPostBackDataHandler, IPostBackEventHandler
{
///
/// 1. 初始化
///
///
protected override void OnInit(EventArgs e)
{
Output("1. OnInit");
base.OnInit(e);
this.Page.RegisterRequiresPostBack(this);
}

///
/// 2. 裝載檢視
///
///
protected override void LoadControlState(object savedState)
{
Output("2. LoadControlState");
base.LoadControlState(savedState);
}

///
/// 3. 回傳資料處理
///
///
///
///
public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
Output("3. LoadPostData");
return true;
}

///
/// 4. 載入事件
///
///
protected override void OnLoad(EventArgs e)
{
Output("4. OnLoad");
base.OnLoad(e);
}

///
/// 5. 回傳事件通知
///
public virtual void RaisePostDataChangedEvent()
{
Output("5. RaisePostDataChangedEvent");
}

///
/// 6. 觸發回傳事件
///
///
public virtual void RaisePostBackEvent(string eventArgument)
{
Output("6. RaisePostBackEvent");
}

///
/// 7. 預呈現
///
///
protected override void OnPreRender(EventArgs e)
{
Output("7. OnPreRender");
base.OnPreRender(e);
}

///
/// 8. 儲存檢視狀態
///
///
protected override object SaveViewState()
{
Output("8. SaveViewState");
base.SaveViewState();
return new Pair();
}

///
/// 9. 呈現
///
///
protected override void Render(HtmlTextWriter writer)
{
writer.Write("",
"[控制元件生命週期]", Page.ClientScript.GetPostBackEventReference(this, ""));
Output("9. Render");
base.Render(writer);
}

///
/// 10. 解除安裝
///
///
protected override void OnUnload(EventArgs e)
{
Output("10. OnUnload");
base.OnUnload(e);
}

///
/// 11. 釋放資源
///
public override void Dispose()
{
Output("11. Dispose");
base.Dispose();
}

private void Output(string content)
{
if (!this.DesignMode)
{
HttpContext.Current.Response.Write(content + "
");
}
}
}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-742941/,如需轉載,請註明出處,否則將追究法律責任。

相關文章