View State 在 Asp.Net 的 postback 机制中有着举足轻重的地位,但是在带宽紧张的环境下(比如跨国访问)庞大的hiddenfield 往往成为系统瓶颈。有什么办法可以在服务器端保存View State吗?答案是肯定的。
方法一:
The Code Project 上的一篇文章Keep ASP.NET ViewState out of ASPX Page for Performance Improvement ,采用override Page 的SavePageStateToPersistenceMedium 和LoadPageStateFromPersistenceMedium 两个方法,把View State存储在Session或cache中。
但是这种方法总显的过于繁琐,有没有什么更简便的方法呢?
方法二:
ASP.NET 2.0 Quick Start中有这么一段
HiddenFieldStatePersister
(it is the VIEWSTATE hidden field). You can override the PageStatePersister
on the Page
for custom persistence however. Given the adaptive nature of controls to the requesting device, some devices may not handle significant amounts of data that are typically 'round-tripped'. Through the PageAdapter
configured for a device, the state can be persisted to alternative sources. ASP.NET 2.0 defines two page state persisters, HiddenFieldPageStatePersister
and SessionPageStatePersister
.
其实ASP.NET 2.0中已经内置了把ViewState存贮在Session中的SessionPageStatePersister,只要override Page的PageStatePersister属性,把返回HiddenFieldPageStatePersister 改为返回SessionPageStatePersister就可以了。这样实在是很方便哦。
但是我又发现了一件很不爽的事情,我们来看一下Page.PageStatePersister的代码:
{
get
{
if ( this ._persister == null )
{
PageAdapter adapter1 = this .PageAdapter;
if (adapter1 != null )
{
this ._persister = adapter1.GetStatePersister();
}
if ( this ._persister == null )
{
this ._persister = new HiddenFieldPageStatePersister( this );
}
}
return this ._persister;
}
}
我们虽然可以重载PageStatePersister属性,却不能修改_persister。在Page的其他很多地方是直接调用_persister的。这样可能会造成某种程度的不一致。
有什么办法呢?注意到上面的那个PageAdapter吗?我们就拿它开刀。
方法三:
首先写一个我们自己的PageAdapter
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
namespace my
{
public class PageStateAdapter : System.Web.UI.Adapters.PageAdapter
{
public override PageStatePersister GetStatePersister()
{
return new SessionPageStatePersister( this .Page);
}
}
}
然后在站点下添加App_Browsers目录,并在目录下添加PageStateAdapter.browser :
< browser refID ="Default" >
< controlAdapters >
< adapter controlType ="System.Web.UI.Page" adapterType ="my.PageStateAdapter" />
</ controlAdapters >
</ browser >
</ browsers >
好了我们的Server Side View State完成了,你可以比较一下前后生成的文件大小,越是复杂的页面效果越明显。当然这是以牺牲服务器性能为代价的。需要注意的是:所谓的server side,还要依赖于站点的session的存贮方式是如何配置的,不过这不在本文的讨论范围之内。
注意:下列服务器控件不能禁止ViewState
Textbox
Checkbox
Checkbox List
RadioButtonList
上面控件的状态通过IPostBackEventHandler 和 IPostBackDataHandler接口处理,而不是ViewState的机制,所以EnableViewState没有效果。
最干净的方法是去掉<form runat=server> 表单
如果你的程序允许的话,
<input type="hidden" name="__VIEWSTATE" value="...">
会消失的无影无踪
要查看页面中控件的ViewState使用情况可以在ASP.NET页面Trace中查看
http://www.zzchn.com/edu/20080727/90699.shtml