如果您有包含许多项目的下拉列表,并且如果这些下拉列表的内容可以在页面回发中轻松检索,则不应将此内容放入视图状态。相反,应在每次回发时在服务器上重新填充下拉列表。典型的例子是一个包含 50 个州的下拉列表。将此内容放入视图状态是没有意义的。此数据可以缓存在服务器上,并用于在每次回发时重新填充下拉列表,而不是在每次往返时将此数据来回传递给客户端。
那么,如何在不将内容添加到视图状态且不关闭控件的视图状态的情况下将内容绑定到下拉列表?答案在于对 ASP.Net 事件管道的理解。在 OnInit 页面事件之后调用 TrackViewState() 方法时的 Viewstate 跟踪对象。在 TrackViewState() 执行后以编程方式对控件进行的任何更改都将放入视图状态。因此,如果您在 Page_Load 事件中对下拉列表进行数据绑定,下拉列表的全部内容将被放入您通常不想要的视图状态。
因此,如果您不希望将下拉列表内容序列化为视图状态,则必须在执行 TrackViewState() 方法之前进行数据绑定。执行此操作的最佳位置是在下拉列表的 Init 事件中。所以长话短说,在它的初始化中填充你的下拉列表,下拉列表的内容不会被序列化到视图状态中。当然,由于内容不在视图状态中,您需要在每次回发时重新填充它。但是,如果内容被缓存并且检索起来很便宜(例如,50 个状态的列表就是这种情况),那么这不是问题。
示例:假设您有一个名为“dropDownList1”的下拉列表,您可以在名为 GetData() 的方法中检索包含列表内容的列表。您可以在 page_load 事件中填充此列表:
protected void Page_Load(object sender, EventArgs e)
{
//Content of dropdown list will be serialized into viewstate
dropDownList1.DataSource = GetData();
Page.DataBind();
}
但如果你这样做,内容将被序列化为视图状态。如果您在其 Init 事件中填充列表:
protected void dropDownList1_Init(object sender, EventArgs e)
{
//Content of dropdown list will NOT be serialized into viewstate
GetData().ForEach(item => this.dropDownList1.Items.Add(item));
}
内容不会被序列化为视图状态。只要检索此内容的成本较低,您就应该这样做。
有关这方面的更多信息,请参阅 Infinities Loop 上的 this excellent article。这是我见过的关于视图状态的最好的文章,通过了解这篇文章的内容,我们能够开始在我们的网页上更智能地使用视图状态并显着减小视图状态的大小。