[ASP.NET][Web Form]PostBack時失去Label的Text

最近同事在Client-side修改asp.net web form控制項的內容,但postback到Server-Side後抓不到值,同事發生問題的控制項是Label,但我們常使用的TextBox控制項則可以,另外根據MSDN上的說明,使用 Label 控制項可以用來顯示在頁面上設定位置的文字,好,馬上實驗Http Request內容是否有帶postdata?

 

建立環境:

1.新增ViewStateAndPostData.aspx

  分別建立三個會在前端修改值的控制項,依序為Textbox、HiddenField及Label,同時新增兩個按鈕,分別是client端事件按鈕及postback回server side的按鈕。

  在client事件中會分別將三個控制項的值依序改為iPhone8、S8 Edge及xz premium。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ViewStateAndPostData.aspx.cs" Inherits="WebApplication1.ViewStateAndPostData" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script>
        function changeText() {
            document.getElementById("txtInPut").value = "iPhone8";
            document.getElementById("hdfInPut").value = "S8 Edge";
            document.getElementById("lblInPut").innerHTML = "xz premium";
        };
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="txtInPut" runat="server"></asp:TextBox>
            <asp:HiddenField ID="hdfInPut" runat="server"></asp:HiddenField>
            <asp:Label ID="lblInPut" runat="server"></asp:Label>
            <button type="button" onclick="changeText()">手機型號</button>
            <asp:Button ID="btnPost" Text="PostBack的按鈕" runat="server" OnClick="btnPost_Click" />
        </div>
    </form>
</body>
</html>

 

2.按F7切換到code behind(ViewStateAndPostData.aspx.cs)

a.若是第一次載入頁面,則將三個控制項依序帶入apple、samsung及sony。

b.依序在Page_Init、Page_Load、post_back event及Page_PreRender觀察三個控制項的值

protected void Page_Init(object sender, EventArgs e)
{
    Debug.WriteLine($"Page_Init Text = {this.txtInPut.Text}");
    Debug.WriteLine($"Page_Init HidenField= {this.hdfInPut.Value}");
    Debug.WriteLine($"Page_Init Label = {this.lblInPut.Text}");
}

protected void Page_Load(object sender, EventArgs e)
{
    Debug.WriteLine($"Page_Load Text = {this.txtInPut.Text}");
    Debug.WriteLine($"Page_Load HidenField= {this.hdfInPut.Value}");
    Debug.WriteLine($"Page_Load Label = {this.lblInPut.Text}");
    if (!Page.IsPostBack)
    {
        this.txtInPut.Text = "apple";
        this.hdfInPut.Value = "samsung";
        this.lblInPut.Text = "sony";
    }
}

protected void btnPost_Click(object sender, EventArgs e)
{
    Debug.WriteLine($"btnPost_Click Text = {this.txtInPut.Text}");
    Debug.WriteLine($"btnPost_Click HidenField= {this.hdfInPut.Value}");
    Debug.WriteLine($"btnPost_Click Label = {this.lblInPut.Text}");
}

protected void Page_PreRender(object sender, EventArgs e)
{
    Debug.WriteLine($"Page_PreRender Text = {this.txtInPut.Text}");
    Debug.WriteLine($"Page_PreRender HidenField= {this.hdfInPut.Value}");
    Debug.WriteLine($"Page_PreRender Label = {this.lblInPut.Text}");
}

 


實驗

1.第一次執行畫面: 

在Page Render之前,判斷使用者第一次載入網頁(非Page.IsPostBack)時的預設值apple、samsung及sony都有在。

 Ctrl + Alt + O 看輸出

2.按下F12 開發人員工具,網路>啟動錄製

3.點選手機型號(Client-Side Button)

A.從肉眼觀察畫面,此時textbox中的apple被javascript方法changeText()換成iphone8了、label也被置換成xz premium。

 

B.打開網頁原始檔(Ctrl + U) 觀察raw HTML 

 HTML原始檔中,只有Label(span標籤)沒有改變,還是維持著Server-Side初始給的sony!

 

C.從F12開發人員工具中的DOM總管:

經過client-side script處理後的網頁,三個手機型號的值都帶出來了!

 

4. 點選postback的按鈕(Server-Side Button),這時可以發現F12 開發人員工具有錄到request。

Request Header

Request Content

Postdata只有iphone8(textbox)及s8 edge(hidenfield),Label果然沒有帶postdata(變更後的值xz premium)

 

5.Decode viewstate: 好在至少還有修改前的狀態sony。

回到Label目的:  顯示在頁面上設定位置的文字!

沒有postdata好像也合情合理的。

 

6.從server-side的偵錯輸出(Ctrl + ALt + O)也反應出同事的問題,textbox、hidenfield都依序載入viewstatepostdata,但label只能載入viewstate,值還是維持sony

 


ASP.NET載入Viewstate及Postdata順序

https://msdn.microsoft.com/en-us/library/ms972976.aspx

 


補充:

順便筆記同事另一個viewstate問題: 這個案例中,為什麼viewstate只有Label的?

因為Textbox和HiddenField都會實作IPostDataHandler,背後會自己處理,這也是停用這些有實作IPostDataHandler控制項viewstate不太有幫助的原因。


 


小結:

  • 解決問題的方式就是用hidenfield來藏client-side的值,postback到server-side再來接。
  • 每次幫新學ASP.NET的同事Debug都有新收穫。

 


參考: 

TextBox 類別

HiddenField 類別

Label 類別

losing Label text on postback help

Understanding ASP.NET View State