2016-11-10 28 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