1、大部分ASP.NET服务器控件是通过ViewState的方式储存其属性值的;
2、任何赋值给ViewState的变量都会被装箱为Object类型的变量;
3、在调用了TrackViewState()方法后,StateBag才开始跟踪其所包含项值的变化;
4、在TrackViewState()方法调用后,只要是出现了赋值操作那么就会使其被标记为脏数据,StateBag并不会判断赋值前后对应项的值是否出现了变化;
5、在_ViewState隐藏变量中存储的Base64编码的字符串,存储的数据是ViewState中那些被标记为Dirty的项;
6、一些常见的ViewState使用错误(IMPROPER USE OF VIEWSTATE):
· 为服务器端控件(webcontrol)设置默认值(Forcing a Default),尽量不要去重写OnLoad或者OnInit事件对控件赋默认值,会使页面的ViewState变大,这是因为TrackViewState()方是在OnInit阶段就开始调用了,从控件树的底部递归调用每个子控件的TrackViewState()方法,最后一个调用的就是控件树的根节点(Page),所以在Page.OnInit阶段的时候对动态控件进行操作的话,那么页面的子控件的TrackViewState已经被调用了,所以这个时候赋值的数据也会被标记为脏数据(dirty data)并最终被ViewState进行持久化保存,例如:<asp:Label id="lblDate" runat="server" />
protected override void OnInit(EventArgs args)
{
this.lblDate.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
base.OnInit(e);
}
(提示:未设置EnableViewState="false"属性!)
· 持久化静态数据(Persisting static data),在页面的生命周期中、一个用户会话中不会被改变的数据:
(1) 使用Literal控件来替代Label控件:<asp:Literal id="litUserName" runat="server" EnableViewState="false"/>
(2) 持久化廉价的数据(Persisting cheap data) :
<asp:DropdownList id="lstStates" runat="server" DataTextField="StateName" DataValueField="StateCode" EnableViewState="false" />
protected override void OnInit(EventArgs args)
{
this.lstStates.DataSource = QueryDatabase();
this.lstStates.DataBind();
base.OnInit(e);
}
(小提示:此种方法会造成对数据库的频繁读取,还是要慎重使用!)
· 通过编码的方式初始化子控件(Initializing child controls programmatically):
(1)在控件的OnInit事件对其进行赋值操作(Declaratively hook into the Init event), 如:
<asp:Label id="Label2" runat="server" OnInit="lblDate_Init" />
在后台编写Label.OnInit事件对应的响应函数并对Label.Text赋初值。
(2)创建用户自定义组件(Create a custom control):
public class DateTimeLabel: Label
{
public DateTimeLabel()
{
this.Text = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss");
}
}
(小提示:在ASP.NET 2.0及以后的版本中已经为我们提供了一些先于OnInit阶段的阶段,如:OnPreInit阶段)
· 以编码的方式创建动态控件(Initializing dynamically created controls programmatically),如:
public class MyCustomControl: Control
{
protected override void OnInit(EventArgs args)
{
DropDownList states = new DropDownList();
states.DataSource = this.GetDataFromDatabase();
states.DataBind();
this.Controls.Add(states);
}
}
这样做的好处还有,由于DropDownList的EnableViewState = true,所以DropDownList依然可以触发诸如OnSelectedIndexChanged事件。也可以对同样的方法操作DataGrid控件,但是可能对于使用DataGrid的排序(sorting),分页(paging)还有SelectedIndex属性还是存在问题。
参考:http://www.360doc.com/content/11/0303/18/6075898_97827350.shtml