服务器端控件带来的好外我在这就不多说了,但多过的使用服务器端件保存控件的状态会带来大量的ViewState的情况大家一定遇到过吧.过多的ViewState会很大程度上降低页面的加载速度制成服务器端的性能下降.
以下是结合CSharpZipLib对ViewState进行压缩的方法.
MSPlus.Web.UI.Page 源码:
using
System;
using
System.Web.UI;
using
System.IO;
using
ICSharpCode.SharpZipLib.Zip.Compression;

namespace
MSPlus.Web.UI

...
{

/**//**//**//// <summary>
/// PageClass 的摘要说明。
/// </summary>
public class Page : System.Web.UI.Page

...{

/**//**//**//// <summary>
/// 设定序列化后的字符串长度为多少后启用压缩
/// </summary>
private static Int32 LimitLength = 1096;


/**//**//**//// <summary>
/// 设定压缩比率,压缩比率越高性消耗也将增大
/// </summary>
private static Int32 ZipLevel = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_COMPRESSION;


/**//**//**//// <summary>
/// 重写保存页的所有视图状态信息
/// </summary>
/// <param name="pViewState">要在其中存储视图状态信息的对象</param>
protected override void SavePageStateToPersistenceMedium(Object pViewState)

...{
//实现一个用于将信息写入字符串的 TextWriter
StringWriter mWriter = new StringWriter();

//序列化 Web 窗体页的视图状态
LosFormatter mFormat = new LosFormatter();

//将有限对象序列化 (LOS) 格式化的对象转换为视图状态值
mFormat.Serialize(mWriter, pViewState);

//将序列化对象转成Base64字符串
String vStateStr = mWriter.ToString();

//设置是否启用了加密方式,默认情况下为不启用
Boolean mUseZip = false;

//判断序列化对象的字符串长度是否超出定义的长度界限
if(vStateStr.Length > LimitLength)

...{
//对于长度超出阶线的进行加密,同时将状态设为加密方式
mUseZip = true;

Byte[] pBytes = Compress(vStateStr);

//将字节数组转换为Base64字符串
vStateStr = System.Convert.ToBase64String(pBytes);
}

//注册在页面储存ViewState状态的隐藏文本框,并将内容写入这个文本框
RegisterHiddenField("__MSPVSTATE", vStateStr);

//注册在页面储存是否启用压缩状态的文本框,并将启用状态写入这个文本框
RegisterHiddenField("__MSPVSTATE_ZIP", mUseZip.ToString().ToLower());
}


/**//**//**//// <summary>
/// 对字符串进行压缩
/// </summary>
/// <param name="pViewState">ViewState字符串</param>
/// <returns>返回流的字节数组</returns>
public static Byte[] Compress(String pViewState)

...{
//将存储状态的Base64字串转换为字节数组
Byte[] pBytes = System.Convert.FromBase64String(pViewState);

//创建支持内存存储的流
MemoryStream mMemory = new MemoryStream();

Deflater mDeflater = new Deflater(ZipLevel);
ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream mStream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(mMemory,mDeflater,131072);

mStream.Write(pBytes,0,pBytes.Length);
mStream.Close();

return mMemory.ToArray();
}


/**//**//**//// <summary>
/// 重写将所有保存的视图状态信息加载到页面对象
/// </summary>
/// <returns>保存的视图状态</returns>
protected override Object LoadPageStateFromPersistenceMedium()

...{
//使用Request方法获取序列化的ViewState字符串
String mViewState = this.Request.Form.Get("__MSPVSTATE");
//使和Request方法获取当前的ViewState是否启用了压缩
String mViewStateZip = this.Request.Form.Get("__MSPVSTATE_ZIP");

Byte[] pBytes;

if(mViewStateZip == "true")

...{
pBytes = DeCompress(mViewState);
}
else

...{
//将ViewState的Base64字符串转换成字节
pBytes = System.Convert.FromBase64String(mViewState);
}

//序列化 Web 窗体页的视图状态
LosFormatter mFormat = new LosFormatter();

//将指定的视图状态值转换为有限对象序列化 (LOS) 格式化的对象
return mFormat.Deserialize(System.Convert.ToBase64String(pBytes));
}


/**//**//**//// <summary>
/// 解压缩ViewState字符串
/// </summary>
/// <param name="pViewState">ViewState字符串</param>
/// <returns>返回流的字节数组</returns>
public static Byte[] DeCompress(String pViewState)

...{
//将Base64字符串转换为字节数组
Byte[] pBytes = System.Convert.FromBase64String(pViewState);

ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream mStream = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(new MemoryStream(pBytes));
//创建支持内存存储的流
MemoryStream mMemory = new MemoryStream();
Int32 mSize;

Byte[] mWriteData = new Byte[4096];

while(true)

...{
mSize = mStream.Read(mWriteData, 0, mWriteData.Length);
if (mSize > 0)

...{
mMemory.Write(mWriteData, 0, mSize);
}
else

...{
break;
}
}

mStream.Close();
return mMemory.ToArray();
}

}
}
使用方法(ASPX.CS页面继承MSPlus.Web.UI.Page):public class PageClass : System.Web.UI.Page
测试下来的结果:压缩后的ViewState只有原来的20%!
我作了一个小小的测试.先后用同一个页面加密和不加密的情况下,刷新页面观测w3wp.exe的CPU占用情况.此页面的ViewState大小为3.996 Bytes
w3wp.exe 以下是每次刷新的时CPU的情况
05 03 05 03 06 05 05 08 03 05 03 不加密,平均是 4.6
05 05 06 05 05 03 08 02 03 05 06 加密,平均是5.3