我以为我理解了ViewState,但这有点奇怪。
我有一个包含1000个标签和文本框的页面,如下所示:
<dt>
<asp:Label runat="server" ID="Label1" AssociatedControlID="TextBox1">Label1</asp:Label>
</dt>
<dd>
<asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
</dd>
所有增加1.我在顶部添加了一个按钮:
<asp:Button runat="server" ID="PostBack" Text="Post it all back!" OnClick="ChangeValues"/>
,相应的代码是:
protected void ChangeValues(object sender, EventArgs e)
{
for (int i = 1; i <= 1000; i++)
{
string textBoxId = "TextBox" + i;
((TextBox)Page.FindControl(textBoxId)).Text = textBoxId;
}
}
所以我理解的是:
现在对于1000个控件,你会发现它相当大,比这更大:
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNjYzODc0MDE1ZGQRGHqYtZTbbkevIfg33I4Wja+xfz0at0+fDMS72BtZNA==" />
我想我在这里错过了一招。我已打开Trace=true
,并注意到所有ViewState仍为0字节。 EnableViewState
和ViewStateMode
未在<@Page
指令中声明,因此ViewState已启用并正在运行。
任何人都可以帮助我理解为什么我误解了这是如何工作的?
答案 0 :(得分:2)
也许是因为TextBox的Text属性不需要保存到ViewState,因为它将呈现给页面并使用发布数据回发。
如果你看一下使用Reflector的TextBox
的实现,你会发现它有一个属性SaveTextViewState
来控制是否需要将Text属性保存到ViewState:
protected override object SaveViewState()
{
if (!this.SaveTextViewState)
{
// This means the Text property will not be saved to ViewState
this.ViewState.SetItemDirty("Text", false);
}
return base.SaveViewState();
}
如果需要保存ViewState(例如TextBox不可见),SaveTextViewState
将返回true,Text属性将保存到ViewState。
<强>更新强>
根据Reflector,SaveTextViewState
属性(用于确定Text
是否需要持久化到ViewState的属性)的实现如下:
private bool SaveTextViewState
{
get
{
if (this.TextMode == TextBoxMode.Password) return false;
}
if (((base.Events[EventTextChanged] == null) &&
base.IsEnabled) &&
((this.Visible && !this.ReadOnly) &&
(base.GetType() == typeof(TextBox))))
{
return false;
}
return true;
}
}
即。如果Text
不是密码文本框并且满足以下任何条件,则TextBox
会持久保存到ViewState:
存在TextChanged事件的处理程序(在这种情况下,它需要原始值来检测文本是否已更改)
禁用控件(在这种情况下,文本不会被回发)
控件不可见(在这种情况下,它不会被渲染)
控件是只读的(文本不会回发)
控件类型不是{{1}}(不要通过抑制ViewState进行优化,因为这可能会影响派生控件的实现)。
本质上是一种优化,如果确定不需要ViewState,则会抑制它。
答案 1 :(得分:0)
答案是实施IPostBackEventHandler
等Textbox, Checkbox
等实施的控件将保留状态even after disabling the viewstate
。原因是在Load Postback Data阶段,这些控件将从Posted back form获取状态信息。
但是像label这样没有实现IPostBackEventHandler的控件将不会从发布的数据中获取任何状态信息,因此完全依赖于viewstate来维护状态。