2016-11-10 55 views
5

我知道即使ViewState被禁用TextBox,我們也不會丟失數據,因爲它實現了IPostBackDataHandler接口。爲什麼標籤的價值改變了?

<asp:TextBox ID="TextBox1" runat="server" EnableViewState="False"/> 

但我的問題是爲什麼這也發生在標籤呢?爲什麼標籤不會丟失數據,即使ViewState被禁用,因爲標籤沒有實現IPostBackDataHandler接口?

<asp:Label ID="Label1" runat="server" EnableViewState="False" ViewStateMode="Disabled"/> 

文本框定義:

public class TextBox : WebControl, IPostBackDataHandler, 

標籤的定義:

public class Label : WebControl, ITextControl 

我的代碼:

<form id="form1" runat="server"> 
<div> 
    <asp:Label ID="Label1" runat="server" EnableViewState="False" ViewStateMode="Disabled" Text="Before click"></asp:Label> 
    <asp:TextBox ID="TextBox1" runat="server" EnableViewState="False"></asp:TextBox> 
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_OnClick"/> 
</div> 
</form> 

而後面的代碼:

protected void Button1_OnClick(object sender, EventArgs e) 
{ 
    Label1.Text = "Changed."; 
} 

點擊按鈕後,我希望看到標籤中的「點擊之前」,但點擊按鈕後,我看到標籤中的「已更改」文本。

+1

你叫什麼「數據」?文本在標籤和文本框上?如果是這樣,這個文本如何在標記中設置? – Andrei

+0

@Andrei在按鈕上單擊我寫這TextBox1.Text =「已更改」; Label1.Text =「已更改。」;我希望標籤會丟失數據,因爲我禁用了viewstate並且它沒有實現IPostBackDataHandler。 –

+0

好吧,數據的含義很清楚,但不是「失去」的意思。所以你點擊改變文字。現在你期望什麼?頁面加載和控件具有「更改」以外的值?或者下一次回傳發生並且控件具有除「已更改」之外的其他值? – Andrei

回答

0

UPD:

我認爲你有錯誤的理解ViewState是什麼。

ViewState中的數據正在存儲BETWEEN請求,但不存儲頁面生命週期。 BTW - 在SaveStateComplete事件中的PreRenderComplete事件之後生成ViewState數據。

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

如果你有ViewState的關閉 - 只是認爲它不會在輸出中產生。

在頁面生命週期中,所有分配給控件(以及頁面字段和屬性,因爲頁面只是一個類)的數據將按照在aspx中定義的方式呈現。但之後會丟失,除非保存在ViewState中。

+0

感謝您的答案。但我的問題是爲什麼EnableViewState = false不適用於標籤。 –

+0

@ user5032790標籤按預期工作,您的期望是錯誤的。你確切知道視圖狀態是什麼,當你禁用它時什麼都不起作用? – Maarten

+0

@Maarten當我點擊標籤的文本時,它會觸發回發,因爲我禁用了標籤上的視圖狀態,所以更改後的文本應該消失。這是不是預期的行爲?還請告訴我是不是按鈕點擊做回傳? –

0

好的,我刪除了我以前的答案,我會嘗試用一個例子重新說明它。

首先,正如其他人所說,ViewState的想法是在回發之間保持狀態,而不是在單個頁面加載週期內,所以你看到的是預期的行爲。

要看到一個例子不同,嘗試用2個按鈕添加您的標籤:

<asp:Label ID="Label1" runat="server" EnableViewState="False" Text="Before click"></asp:Label> 
<asp:Button ID="btn1" Text="Click" OnClick="btn1_Click" runat="server" /> 
<asp:Button ID="btnReset" Text="Reset" OnClick="btnReset_Click" runat="server" /> 

btn1將值設置爲「已更改」,並btnReset有一個空的處理程序。

EnableViewState

現在設置爲False,如果您在btn1點擊頁面重新加載,btn1_Click被執行,並且該頁面會呈現與標籤值=「更改」,如果你點擊btnReset頁面會重新加載,但由於視圖狀態被禁用時,標籤將恢復到原來的文字「前點擊」

如果您在拉布勒設置EnableViewStateTrue並單擊btn1然後btnReset,標籤值將保持爲「改變」,因爲國家是在回寄期間保留

希望澄清事情有點

+0

那麼你是否試圖說在點擊btn1和btn1_Click之後設置標籤的值是在回發之後?對? –

+0

而且我改變了文本後,在瀏覽器中呈現的結果稱爲** Response **或什麼? –

+0

按鈕處理程序在* postback期間執行*在瀏覽器中呈現的內容是由服務器發送的HTTP響應的一部分是的..你可能想看看這裏的答案http://stackoverflow.com/questions/8457297/asp-net-page-life-cycle-explanation如果你不熟悉ASP.NET頁面的生命週期 – KMoussa

0

這將是漫長而詳細的。

讓我們從這個標記開始。幾乎與你的一樣,只需一個按鈕和一個標籤。我會解釋爲什麼我們稍後需要它們。

<form id="form1" runat="server"> 
<div> 
    <asp:Label ID="Label1" runat="server" EnableViewState="False" ViewStateMode="Disabled" Text="Before click"></asp:Label> 
    <asp:TextBox ID="TextBox1" runat="server" EnableViewState="False"></asp:TextBox> 
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_OnClick"/> 

    <asp:Label ID="Label2" runat="server" Text="Blah" /> 
    <asp:Button ID="Button2" runat="server" Text="Button" OnClick="Button2_OnClick"/> 
</div> 
</form> 

我們將在後面使用此代碼。再次,我將在後面解釋第二個處理程序的用途:

protected void Button1_OnClick(object sender, EventArgs e) 
{ 
    Label1.Text = "Changed"; 
} 

protected void Button2_OnClick(object sender, EventArgs e) 
{ 
    Label2.Text = Label1.Text; 
} 

讓我們來看看最初加載頁面時會發生什麼。第一個ASP.NET讀取所有標記,然後通過所有事件遍歷頁面生命週期。在標記解析階段Label1獲得分配文本Before click,並且它在初始加載期間不會在以後更改。所以後來的渲染階段就是渲染成HTML併發送到瀏覽器的東西。因此屏幕上顯示Before click。好,易於。我們點擊Button1。回傳發生,這是一個術語,描述一個控件在最初加載之後通過其中一個控件發送到同一頁面的請求。再次,所有事情都從ASP.NET解析標記開始,並且Label1再次獲得分配文本Before click。但是,頁面生命週期事件發生,包含控件事件處理程序。並在Button1的處理程序Label1的文本更改爲Changed。現在這是重要的事情要注意。如果啓用了Label1的ViewState,則此新值將存儲在那裏,因此將爲屬性Label1.Text啓用所謂的跟蹤。但ViewState被禁用,因此新值不會存儲在除Label1之外的任何地方。接下來是渲染頁面階段,並且由於Label1.Text仍然保留值Changed,這是呈現爲HTML並被髮送到瀏覽器以顯示的內容。但請注意,此新值不會在ViewState字段內發送。正如你所看到的,是否啓用ViewState在回發後顯示的內容中不起作用。

現在我們將點擊Button2,這會觸發另一個回傳。再次,ASP.NET分析標記,再次Label1獲取文本Before click。然後來ViewState加載部分。如果啓用了ViewState Label1.Text,則會將更改的值加載到此屬性中。但ViewState被禁用,所以值保持不變。因此,當我們到達Button2點擊處理程序時,Label1.Text的值仍爲Before click,該值分配給Label2.Text。但Label2已啓用ViewState,因此其文本的這個新值存儲在ViewState中併發送到客戶端(ViewState作爲客戶端的隱藏字段實現)。當一切都進入瀏覽器時,我們可以看到Label1Label2都顯示爲Before click

而要確定它,我們會做第三次回傳,現在再次點擊Button1。就像在第一次回發期間,Label1Changed文本結束。但是Label2呢?那麼,這個ViewState被啓用,所以在初始標記解析ASP.NET分配它的值爲Blah,並且在ViewState加載期間它將用Before click代替該值。在頁面生命週期中沒有其他因素影響這個值(我們沒有點擊Button2),所以我們最終在瀏覽器中看到了ChangedBefore click

希望它明確了ViewState的作用和禁用它的功能。如果你想深入瞭解ViewState的工作原理,我會非常推薦這篇文章:TRULY Understanding ViewState