我已经找到了减少ViewState的方法:
但是,由于我所处的情况,我需要最快捷,最有效的方法来减少ViewState的大小。我正在研究的遗留系统很臃肿,并且在多个回发中通常具有800Kb +的ViewState。
例如,我很确定在多个帖子上填充100多个项目的下拉列表是其中一个罪魁祸首,对吗?
任何建议/意见都将不胜感激。
修改1 完全禁用ViewState似乎不可行。它打破了所有控件,其中有很多控件,使页面无法使用。如果这是最好的方法,我该如何处理所有损坏的控件?
答案 0 :(得分:5)
如果您有包含许多项目的下拉列表,并且如果可以在页面回发中轻松检索这些下拉列表的内容,则不应将此内容放入视图状态。相反,应在每次回发时在服务器上重新填充下拉列表。典型的例子是下拉列表,其中包含50个州的列表。将此内容放入视图状态是没有意义的。这些数据可以缓存在服务器上,用于在每次回发时重新填充下拉列表,而不是在每次往返时来回传递这些数据。
那么如何将内容绑定到下拉列表而不将其添加到viewstate,并且不关闭控件的viewstate?答案在于理解ASP.Net事件管道。在OnInit页面事件之后调用TrackViewState()方法时,Viewstate跟踪生物。 TrackViewState()执行后以编程方式对控件进行的任何更改都将放入viewstate。因此,如果您在Page_Load事件中对下拉列表进行数据绑定,则下拉列表的整个内容将被放入viewstate,这通常是您不想要的。
因此,如果您不希望将下拉列表内容序列化到viewstate中,则必须在执行TrackViewState()方法之前进行数据绑定。执行此操作的最佳位置是下拉列表的Init事件。因此,简而言之,在其Init中填充下拉列表,下拉列表内容不会被序列化到viewstate中。当然,由于内容不在视图状态,因此您需要在每次回发时重新填充它。但是,如果内容被缓存并且检索起来很便宜(例如,使用50个状态的列表),那么这不是问题。
示例:假设您有一个名为“dropDownList1”的下拉列表,您可以在名为GetData()的方法中检索包含列表内容的List。您可以在page_load事件中填充此列表:
protected void Page_Load(object sender, EventArgs e)
{
//Content of dropdown list will be serialized into viewstate
dropDownList1.DataSource = GetData();
Page.DataBind();
}
但是如果你这样做,内容将被序列化到viewstate。如果您在其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));
}
内容不会被序列化到viewstate中。只要检索这些内容很便宜,你就应该这样做。
有关此内容的更多信息,请参阅无限循环上的this excellent article。这是我在viewstate上看过的最好的文章,通过理解本文的内容,我们能够在我们的网页上更智能地开始使用viewstate,并大大减少了我们的viewstate大小。
答案 1 :(得分:1)
您可能希望查看压缩视图状态,如this code project页上所述。
注意:我没有试过这个,但似乎它应该有效。
答案 2 :(得分:0)
最快最有效的方法是完全关闭视图状态:
<system.web>
<pages enableViewState="false" />
您也可以为各个页面关闭它:
private void Page_Init(object sender, System.EventArgs e)
{
this.EnableViewState = false;
}
答案 3 :(得分:0)
根据您存储会话的方式(最好是存储数据库),页面获取的流量以及服务器具有的内存量(如果您使用的是InProc会话),您可以将视图状态存储在会话中。这很容易做到,缺点是存在陷阱,并不适用于所有网站。
这是一篇很好的文章,概述了流程的基础知识以及一些缺点/陷阱:
http://www.hanselman.com/blog/MovingViewStateToTheSessionObjectAndMoreWrongheadedness.aspx