压缩 ViewState 后,与 UpdatePanel 的兼容问题
2007-05-02 18:09
381 查看
为了节省带宽,可能需要压缩一下 ViewState ,具体压缩的代码,网上一搜一大把,比如下面这段:
public class CompressedViewStatePage : System.Web.UI.Page
public class CompressedViewStatePage : System.Web.UI.Page
{
protected override void SavePageStateToPersistenceMedium(object state)
{
Pair pair;
PageStatePersister persister = this.PageStatePersister;
object viewState;
if (state is Pair)
{
pair = (Pair)state;
persister.ControlState = pair.First;
viewState = pair.Second;
}
else
{
viewState = state;
}
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateStr = writer.ToString();
byte[] data = Convert.FromBase64String(viewStateStr);
byte[] compressedData = CompressHelper.Compress(data);
string str = Convert.ToBase64String(compressedData);
persister.ViewState = str;
persister.Save();
}
protected override object LoadPageStateFromPersistenceMedium()
{
PageStatePersister persister = this.PageStatePersister;
persister.Load();
string viewState = persister.ViewState.ToString();
byte[] data = Convert.FromBase64String(viewState);
byte[] uncompressedData = CompressHelper.Decompress(data);
string str = Convert.ToBase64String(uncompressedData);
LosFormatter formatter = new LosFormatter();
return new Pair(persister.ControlState, formatter.Deserialize(str));
}
}
如果用 Reflector 看看 System.Web.UI.Page 类的 SavePageStateToPersistenceMedium 和 LoadPageStateFromPersistenceMedium 方法,你会发现上面的代码和微软的实现差不多,都是使用 Persister.Save 和 Persister.Load 来保存和获取 ViewState (只是上面的代码加上了压缩和解压的逻辑),这里的 Persister 是默认的 HiddenFieldPageStatePersister ,所以页面还是使用 __VIEWSTATE 字段来保存 ViewState。
改成第二段代码来压缩 ViewState 就正常了。至于第一段代码会在 Update Panel 中出问题,我是这样猜的:
启用 UpdatePanel 的局部刷新并不是真正的局部刷新,只不过微软做了点手脚,用 XMLHttpRequest 对象去向服务器提交请求,而服务器毫不知情,还是会生成一个完整的页面生成周期,把生成的 HTML 完整的返回,这时 ScriptManager 把不在 UpdatePanel 里的内容统统去掉,只接收 UpdatePanel 里面的内容,然后在客户端刷新一下,造成局部刷新的“假像”。问题就出在用 XMLHttpRequest 对象去请求服务器的时候,ScriptManager 不知道我们把 ViewState 放在 __COMPRESSEDVIEWSTATE 字段中,而用的是 __VIEWSTATE 字段里的内容,所以服务器会认为用户没有输入查询参数,返回了数据库中的所有记录……
问题好像就是这样产生的,不过我还有点不清楚,Persister.ControlState 和 Persister.ViewState 各是什么意思, MSDN 上也没说太明白,哪位大虾解释一下?
参考
public class CompressedViewStatePage : System.Web.UI.Page
public class CompressedViewStatePage : System.Web.UI.Page
{
protected override void SavePageStateToPersistenceMedium(object state)
{
Pair pair;
PageStatePersister persister = this.PageStatePersister;
object viewState;
if (state is Pair)
{
pair = (Pair)state;
persister.ControlState = pair.First;
viewState = pair.Second;
}
else
{
viewState = state;
}
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateStr = writer.ToString();
byte[] data = Convert.FromBase64String(viewStateStr);
byte[] compressedData = CompressHelper.Compress(data);
string str = Convert.ToBase64String(compressedData);
persister.ViewState = str;
persister.Save();
}
protected override object LoadPageStateFromPersistenceMedium()
{
PageStatePersister persister = this.PageStatePersister;
persister.Load();
string viewState = persister.ViewState.ToString();
byte[] data = Convert.FromBase64String(viewState);
byte[] uncompressedData = CompressHelper.Decompress(data);
string str = Convert.ToBase64String(uncompressedData);
LosFormatter formatter = new LosFormatter();
return new Pair(persister.ControlState, formatter.Deserialize(str));
}
}
如果用 Reflector 看看 System.Web.UI.Page 类的 SavePageStateToPersistenceMedium 和 LoadPageStateFromPersistenceMedium 方法,你会发现上面的代码和微软的实现差不多,都是使用 Persister.Save 和 Persister.Load 来保存和获取 ViewState (只是上面的代码加上了压缩和解压的逻辑),这里的 Persister 是默认的 HiddenFieldPageStatePersister ,所以页面还是使用 __VIEWSTATE 字段来保存 ViewState。
改成第二段代码来压缩 ViewState 就正常了。至于第一段代码会在 Update Panel 中出问题,我是这样猜的:
启用 UpdatePanel 的局部刷新并不是真正的局部刷新,只不过微软做了点手脚,用 XMLHttpRequest 对象去向服务器提交请求,而服务器毫不知情,还是会生成一个完整的页面生成周期,把生成的 HTML 完整的返回,这时 ScriptManager 把不在 UpdatePanel 里的内容统统去掉,只接收 UpdatePanel 里面的内容,然后在客户端刷新一下,造成局部刷新的“假像”。问题就出在用 XMLHttpRequest 对象去请求服务器的时候,ScriptManager 不知道我们把 ViewState 放在 __COMPRESSEDVIEWSTATE 字段中,而用的是 __VIEWSTATE 字段里的内容,所以服务器会认为用户没有输入查询参数,返回了数据库中的所有记录……
问题好像就是这样产生的,不过我还有点不清楚,Persister.ControlState 和 Persister.ViewState 各是什么意思, MSDN 上也没说太明白,哪位大虾解释一下?
参考
相关文章推荐
- Ajax中的UpdatePanel与Freetextbox兼容问题的初步解决方法
- Updatepanel和树不兼容的问题
- ViewState、UpdatePanel及控件OnPre之间的纠葛
- jQuery和UpdatePanel兼容的问题
- ViewState、UpdatePanel及控件OnPre之间的纠葛
- ASP.NET学习笔记[9] - jQuery和UpdatePanel兼容的问题
- ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘
- Ajax中的UpdatePanel与Freetextbox兼容问题
- C#中关于updatePanel与freeTextBox不兼容的问题 当页面刷子新后,ftb不能输入内容的解决办法
- Ajax中的UpdatePanel与Freetextbox兼容问题的初步解决方法
- UpdatePanel和jQuery不兼容问题
- C#中关于updatePanel与freeTextBox不兼容的问题
- 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法
- UpdatePanel 里使用 JQUERY 问题
- 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题 3法
- 有关视图状态(ViewState)的一些问题
- [转]asp:UpdatePanel中FileUpload控件应用问题
- 转载: asp.net ajax UpdatePanel使用技巧以及常见问题
- ViewState优化——压缩技术
- 解决AJAX中使用UpdatePanel后再用Response.Write();等无法弹出对话框问题