2014年2月18日 星期二

C# - Postback生命週期

寫Web程式,不可缺乏的就是資料的傳送過程,最常採用的就是Get和Post這兩種方法。用微軟開發的技術,通常已經把一般寫Web會運用到的原理,透過元件封包,直接在底層處理好了。開發者只要透過reguest這個類別,就可以取得所有的傳送資訊。
網站運作的基本邏輯是:網頁對於伺服器而言是幾近於完全無保留狀態 (Stateless) 的, 所以網頁的每次重新載入 (Postback) 都和第一次載入時一樣; 你反正每次都要從伺服器端把整個網頁都重新傳過來一次。這是早期網頁的運作原理,不過現在的技術導人了Ajax的概念後,很多的技術就改善了這樣的重覆讀取頁面的過程。

因此, 在 PostBack 之後, 一般人認為還在看同一個網頁,但是整個網頁在背景中已經來回重新讀取傳送一遍。因為網頁底層結構運作,讓表單上原本輸入或變化的東西都還會存在,使用者完全看不出來這個網頁其實已經在背景中重新傳過一次了。所以當 Postback 程序完成, 使用者根本感覺不到網頁有重新讀取頁面的感覺, 因為輸入的文字還在、下拉式選單也停留在他上次選擇的項目, 甚至畫面也停留在他原來捲動的地方。


筆者就來介紹PostBack的觀念:

瀏覽器(Browser)會用Get方式向Server取得第一次載入的資料,此時Page屬性IsPostBack=false;然後執行Page_Load程式。之後當Browser觸發了一個按鈕Button後,不管這按扭元件的底下有沒有陳述句,ASP.net會Post的方式重新導向然後執行一次Server端程式碼,IsPostBack會變更為true。當使用者在瀏覽器(Browser)按下了一個按鈕,不管按鈕有沒有寫程式碼,程式預設會利用Post的方式重新導向再次執行一次Server端的程式碼。此時IsPostBack=true。

範例如下:

<asp:Button ID="mybtn" runat="server" Text="Button"/>

上面的ID就是開發者自訂的類別變數名,runat就是在server上執行編譯的過程,基本上只要是Asp.net表單元件,都會有Postback的功能,html控制項加了 type="submit" 也能達到Postback的功能。

範例如下:

<input type="submit" id="mysbt" value="button" />


不過大部分來說ASP.net預設具有Postback功能的就只有Button,其它的控制項若是要具有Postback功能只要將控制項屬性(Properies)上的AutoPostBack設為true即可。不過不是所有的的控制項(Controls)都有這樣的功能。

以下例子是如何自訂Postback Event,沒有postback功能的類別,就利用GetPostBackEventReference 方法設定Attributes[]:

protected void form_ItemDataBound(object sender, EventArgs e)
{
    Label3.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(Label3, string.Empty);
}
private void Label3_OnClick()
{
    Label1.Text = DateTime.Now.ToString();
}


protected void Page_Load(object sender, EventArgs e)
{
    if (Page.IsPostBack)
    {
        Label1.Text = System.DateTime.Now.ToString();
    }
    else
    {
        Label1.Text = "";
    }
}

上面程式碼中,利用Page.IsPostBack判斷網頁是否是第一次執行,以便依判斷式來處理不同的情況。在ASP.net運作原理上, Page_Load() 事件的發生是很後面的,所以初學者在 Page_Load() 程序中才在頁面上動態加入控制項,卻在 Paeg.Load 事件之前就想存取這些控制項。理想上通常要避免動態加入控制項,增進讀取的效能。

初學者還會遇到的問題是 GridView/FormView 等容器的編輯樣板中。由於這些容器有很多事件 ,例如RowDataBound, RowCommand...等,透過Trace可以找到FindControl() 指令下面的結果。

-雲遊山水為知已逍遙一生而忘齡- 電腦神手

沒有留言:

張貼留言