项目报表页面viewState大小超过200K,页面体积很大,必须得将之瘦身,现在很流行身材苗条。。。。。
执行之前
先重载Page中的两个方法:
1、SavePageStateToPersistenceMedium
SavePageStateToPersistenceMedium 方法使用 PageStatePersister 属性所引用的 System.Web.UI.PageStatePersister 对象的 Save 方法存储页的视图状态和控件状态信息。
ASP.NET 包括 PageStatePersister 类的两个子类:在 ASP.NET 页包含的隐藏字段中保存状态信息的 HiddenFieldPageStatePersister 类和在与请求关联的 Session 对象中保存状态的 SessionPageStatePersister 类。 注意,使用SessionPageStatePersister 类时,隐藏的 VIEWSTATE 字段仍将像用于确定回发时那样呈现。
若要在您选择的位置保存状态,应创建 PageStatePersister 类的新子类,它可将状态保存并加载到您所选择的持久性介质中。 有关创建新的 PageStatePersister 对象的示例,请参见 PageStatePersister 类。
使用 .NET Framework 1.0 版或 1.1 版时,如果要从隐藏字段外的其他任何位置保存 Page 状态,则请重写此方法。 如果选择这样做,还必须重写 LoadPageStateFromPersistenceMedium 方法。
2、LoadPageStateFromPersistenceMedium
LoadPageStateFromPersistenceMedium 方法使用 PageStatePersister 属性所引用的 System.Web.UI.PageStatePersister 对象的 Load 方法来为 Page 对象加载任何保存的视图状态信息。
ASP.NET 包括 PageStatePersister 类的两个子类:在 ASP.NET 页包含的隐藏字段中保存状态信息的 HiddenFieldPageStatePersister 类和在与请求关联的 Session 对象中保存状态的 SessionPageStatePersister 类。
若要在您选择的位置保存状态,应创建 PageStatePersister 类的新子类,它可将状态保存并加载到您所选择的持久性介质中。 有关创建新的 PageStatePersister 对象的示例,请参见 PageStatePersister 类。
使用 .NET Framework 1.0 版或 1.1 版时,如果要从隐藏字段外的其他任何位置加载 Page 状态,则请重写此方法。 如果选择这样做,还必须重写 SavePageStateToPersistenceMedium 方法。
一、压缩viewState
先准备GZipHelper类
GZipHelper /// <summary> /// GZip压缩解压缩帮助类 /// </summary> public class GZipHelper { /// <summary> /// GZip压缩 /// </summary> /// <param name="data">The data.</param> /// <returns></returns> public static byte[] Compress(byte[] data) { MemoryStream ms = new MemoryStream(); GZipStream stream = new GZipStream(ms, CompressionMode.Compress); stream.Write(data, 0, data.Length); stream.Close(); return ms.ToArray(); } /// <summary> /// GZip解压缩 /// </summary> /// <param name="data">The data.</param> /// <returns></returns> public static byte[] Decompress(byte[] data) { MemoryStream ms = new MemoryStream(); ms.Write(data, 0, data.Length); ms.Position = 0; GZipStream stream = new GZipStream(ms, CompressionMode.Decompress); MemoryStream temp = new MemoryStream(); byte[] buffer = new byte[1024]; while (true) { int read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) { break; } else { temp.Write(buffer, 0, buffer.Length); } } stream.Close(); return temp.ToArray(); } }
重载SavePageStateToPersistenceMedium
SavePageStateToPersistenceMediumprotected override void SavePageStateToPersistenceMedium(object state) { string viewState = new ObjectStateFormatter().Serialize(state); byte[] data = Convert.FromBase64String(viewState); byte[] compressedData = ViewStateHelper.Compress(data); string str = Convert.ToBase64String(compressedData); ClientScript.RegisterHiddenField("__ARGVVIEWSTATE", str); }
重载LoadPageStateFromPersistenceMedium
LoadPageStateFromPersistenceMediumprotected override object LoadPageStateFromPersistenceMedium() { string viewstate = Request.Form["__ARGVVIEWSTATE"]; byte[] data = Convert.FromBase64String(viewstate); byte[] uncompressedData = ViewStateHelper.Decompress(data); string str = Convert.ToBase64String(uncompressedData); return new ObjectStateFormatter().Deserialize(str); }
结果:较以前页面大小减少了50%,但是所耗CPU要大,耗时要长。
二、保存viewState到服务器
Savestatic private System.IO.DirectoryInfo Dir = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"App_Data\ViewState\")); protected override void OnPreInit(System.EventArgs e) { if (!Dir.Exists) Dir.Create(); else { DateTime nt = DateTime.Now.AddSeconds(-5); foreach (System.IO.FileInfo f in Dir.GetFiles()) { if (f.CreationTime < nt) f.Delete(); } } base.OnPreInit(e); } /// <summary> /// Saves any view-state and control-state information for the page. /// </summary> /// <param name="state"></param> protected override void SavePageStateToPersistenceMedium(object state) { string value = new ObjectStateFormatter().Serialize(state); string viewStateID = (DateTime.Now.Ticks + (long)this.GetHashCode()).ToString(); //产生离散的id号码 string fn = System.IO.Path.Combine(Dir.FullName, viewStateID); System.Threading.ThreadPool.QueueUserWorkItem((obj) => System.IO.File.WriteAllText(fn, value)); //或者只写 File.WriteAllText(fn, value) Cache.Insert(viewStateID, value); base.SavePageStateToPersistenceMedium(viewStateID); } /// <summary> /// 将所有保存的视图状态信息加载到 <see cref="T:System.Web.UI.Page"/> 对象。 /// </summary> /// <returns>保存的视图状态。</returns> protected override object LoadPageStateFromPersistenceMedium() { string viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second; string stateStr = (string)Cache[viewStateID]; if (stateStr == null) { string fn = System.IO.Path.Combine(Dir.FullName, viewStateID); stateStr = System.IO.File.ReadAllText(fn); } else Cache.Remove(viewStateID); return new ObjectStateFormatter().Deserialize(stateStr); }
结果:ViewState从原来的保存在页面变成保存到了服务器,页面viewState大小为0,大大减少页面大小。但是要多做一个清除服务器历史viewstate数据操作。