我知道即使为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;单击按钮后,我的标签中的文字。
答案 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在客户端实现为隐藏字段)。当所有内容都进入浏览器后,我们可以看到Label1
和Label2
都显示Before click
。
为了确定它,我们将进行第三次回发,现在再次点击Button1
。与第一次回发期间一样,Label1
最终会收到Changed
文字。但是Label2
呢?好吧,这个启用了ViewState,因此在初始标记解析期间,ASP.NET会为其赋值Blah
,并且在ViewState加载期间,它会将此值替换为Before click
。在页面生命周期中没有其他任何因素影响此值(我们这次没有单击Button2),因此我们最终在浏览器中看到Changed
和Before click
。
希望它能说明ViewState的用途以及禁用它的功能。如果您想更深入地了解ViewState的工作原理,我强烈推荐这篇文章:TRULY Understanding ViewState