为什么标签的价值会发生变化?

时间:2016-11-10 11:38:32

标签: c# asp.net

我知道即使为TextBox禁用ViewState,我们也不会丢失数据,因为它实现了IPostBackDataHandler接口。

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

但我的问题是为什么标签也会出现这种情况呢?为什么标签不会丢失它的数据,即使ViewState被禁用,因为标签没有实现IPostBackDataHandler接口?

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

TextBox定义:

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.";
}

我希望看到&#34;点击之前&#34;点击按钮后,在我的标签中,但是我看到&#34;已更改&#34;单击按钮后,我的标签中的文字。

3 个答案:

答案 0 :(得分:0)

UPD:

我认为你错误地理解了ViewState是什么。

ViewState中的数据存储在BETWEEN请求中,但不存储在页面生命周期内。 BTW - 在SaveStateComplete事件中的PreRenderComplete事件之后生成ViewState数据。

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

如果关闭了ViewState,只需认为它不会在输出中生成。

在页面生命周期中,分配给控件的所有数据(以及页面字段和属性,因为页面只是一个类)将按照您在aspx中定义的方式呈现。但之后会丢失,除非保存在ViewState中。

答案 1 :(得分: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将值设置为&#34;已更改&#34;,btnReset有一个空处理程序。

现在将EnableViewState设置为False,如果您点击btn1页面重新加载,则会执行btn1_Click,并使用标签值=&呈现页面#34;已更改&#34;,如果您点击btnReset页面将重新加载,但由于视图状态已停用,标签将恢复为原始文字&#34;点击&#34;

如果您在标签上将EnableViewState设置为True,然后点击btn1然后点击btnReset,则标签值将保持为&#34;已更改&#34;,因为在回发期间保持状态

希望能澄清一些事情

答案 2 :(得分: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加载部分。如果启用了Label1.Text的ViewState,则会将更改的值加载到此属性中。但是ViewState被禁用,因此值保持不变。因此,当我们到达Button2点击处理程序时,Label1.Text的值仍为Before click,其分配给Label2.Text。但Label2启用了ViewState,因此其文本的新值存储在ViewState中并发送到客户端(ViewState在客户端实现为隐藏字段)。当所有内容都进入浏览器后,我们可以看到Label1Label2都显示Before click

为了确定它,我们将进行第三次回发,现在再次点击Button1。与第一次回发期间一样,Label1最终会收到Changed文字。但是Label2呢?好吧,这个启用了ViewState,因此在初始标记解析期间,ASP.NET会为其赋值Blah,并且在ViewState加载期间,它会将此值替换为Before click。在页面生命周期中没有其他任何因素影响此值(我们这次没有单击Button2),因此我们最终在浏览器中看到ChangedBefore click

希望它能说明ViewState的用途以及禁用它的功能。如果您想更深入地了解ViewState的工作原理,我强烈推荐这篇文章:TRULY Understanding ViewState