在状态管理中经常要用到ViewState 可是当数据比较大的时候我们可以压缩ViewState。压缩的方式很多,
1。在这里提供通过重写PageStatePersister属性来实现
先写一个压缩的工具类:
public class CompressHelp
{
static LosFormatter formatter = new LosFormatter();
public static object Decompress(string stateString)
{
byte[] buffer = Convert.FromBase64String(stateString);
MemoryStream ms = new MemoryStream(buffer);
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
MemoryStream msReader = new MemoryStream(buffer);
buffer = new byte[0x1000];
while (true)
{
int read = zipStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
msReader.Write(buffer, 0, read);
}
zipStream.Close();
ms.Close();
msReader.Position = 0;
buffer = msReader.ToArray();
stateString = Convert.ToBase64String(buffer);
return formatter.Deserialize(stateString);
}
public static string Compress(object state)
{
StringWriter writer = new StringWriter();
formatter.Serialize(writer, state);
string stateString = writer.ToString();
writer.Close();
byte[] buffer = Convert.FromBase64String(stateString);
MemoryStream ms = new MemoryStream();
GZipStream zipStream = new GZipStream(ms, CompressionMode.Compress, true);
zipStream.Write(buffer, 0, buffer.Length);
zipStream.Close();
buffer = new byte[ms.Length];
ms.Position = 0;
ms.Read(buffer, 0, buffer.Length);
ms.Close();
stateString = Convert.ToBase64String(buffer);
return stateString;
}
}
新增一个CompressPageStatePersister类:
public class CompressPageStatePersister : PageStatePersister
{
string PageStateKey = "_VIEWSTATE";
public CompressPageStatePersister(Page page) : base(page) { }
public override void Load()
{
string postbackState = Page.Request.Form[PageStateKey];
if (!string.IsNullOrEmpty(postbackState))
{
Pair statePair = (Pair)CompressHelp.Decompress(postbackState);
if (!Page.EnableViewState)
this.ViewState = null;
else
this.ViewState = statePair.First;
this.ControlState = statePair.Second;
}
}
public override void Save()
{
if (!Page.EnableViewState)
this.ViewState = null;
if (this.ViewState != null || this.ControlState != null)
{
Pair statePair = new Pair(ViewState, ControlState);
string stateString = CompressHelp.Compress(statePair);
Page.ClientScript.RegisterHiddenField(PageStateKey, stateString);
}
}
}
使用方式,在page页面中:
protected override PageStatePersister PageStatePersister
{
get
{
return new CompressPageStatePersister(this);
}
}
注意:此种实现不支持AJAX,即只能是同步方式
2。重写page的SavePageStateToPersistenceMedium方法和LoadPageStateFromPersistenceMedium方法
首先写一个工具类:
public class Utils
{
public static bool IsMsAjaxCallback(HttpRequest request)
{
return (request != null && request.Headers["X-MicrosoftAjax"] != null);
}
public static byte[] Compress(byte[] data)
{
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
{
zip.Write(data, 0, data.Length);
zip.Dispose();
return ms.ToArray();
}
}
}
public static Byte[] Compress(string viewState)
{
using (MemoryStream ms = new MemoryStream())
{
byte[] data = Convert.FromBase64String(viewState);
Deflater defaulter = new Deflater(Deflater.BEST_COMPRESSION);
DeflaterOutputStream oms = new DeflaterOutputStream(ms, defaulter, 131072);
oms.Write(data, 0, data.Length);
oms.Close();
return ms.ToArray();
}
}
public static byte[] DeCompress(byte[] data)
{
using (MemoryStream ms = new MemoryStream())
{
int dataLength = BitConverter.ToInt32(data, 0);
ms.Write(data, 0, data.Length);
byte[] buffer = new byte[dataLength];
ms.Position = 0;
using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
{
zip.Read(buffer, 0, buffer.Length);
}
return buffer;
}
}
public static Byte[] DeCompress(string viewState)
{
using (MemoryStream ms = new MemoryStream())
{
byte[] data = Convert.FromBase64String(viewState);
InflaterInputStream ims = new InflaterInputStream(new MemoryStream(data));
int msize;
byte[] tempdata = new byte[4096];
while (true)
{
msize = ims.Read(tempdata, 0, tempdata.Length);
if (msize > 0)
ms.Write(tempdata, 0, msize);
else break;
}
ims.Close();
return ms.ToArray();
}
}
}
使用方式
protected override void SavePageStateToPersistenceMedium(object state)
{
LosFormatter formatter = new LosFormatter();
using (StringWriter writer = new StringWriter())
{
formatter.Serialize(writer, state);
string viewState = writer.ToString();
if (Utils.IsMsAjaxCallback(Request))
{
byte[] data = Convert.FromBase64String(viewState);
data = Utils.Compress(data);
ScriptManager.RegisterHiddenField(this, "_COMPRESSEDVS", Convert.ToBase64String(data));
}
else
{
Boolean mUseZip = false;
if (viewState.Length > LimitLength)
{
mUseZip = true;
byte[] data = Utils.Compress(viewState);
viewState = Convert.ToBase64String(data);
}
ScriptManager.RegisterHiddenField(this, "_MSPVSTATE", viewState);
ScriptManager.RegisterHiddenField(this, "_MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
}
}
}
protected override object LoadPageStateFromPersistenceMedium()
{
string viewState = Request.Form["_COMPRESSEDVS"];
LosFormatter formatter = new LosFormatter();
byte[] data;
if (viewState != null && viewState.Length > 0)
{
data = Convert.FromBase64String(viewState);
data = Utils.DeCompress(data);
return formatter.Deserialize(Convert.ToBase64String(data));
}
else
{
viewState = Request.Form.Get("_MSPVSTATE");
bool zip = bool.Parse(Request.Form.Get("_MSPVSTATE_ZIP"));
if (zip) data = Utils.DeCompress(viewState);
else data = Convert.FromBase64String(viewState);
return formatter.Deserialize(Convert.ToBase64String(data));
}
}
在这里用了第三方的工具包ICSharpCode.SharpZipLib
该实例可以在http://download.youkuaiyun.com/source/1864129下载