内存中数据的压缩和解压
首先,我们需要一种方法来压缩和解压缩内存中的字节数组。我将这个简单的静态类放在一起,它公开了两种方法:压缩和解压缩。根据 MSDN,GZipStream 和 DeflateStream 这两个可用的类使用相同的算法,因此选择哪一个无关紧要。
下面的代码很简单,不需要解释:
using System.IO;
using System.IO.Compression;
public static class Compressor {
public static byte[] Compress(byte[] data) {
MemoryStream output = new MemoryStream();
GZipStream gzip = new GZipStream(output,
CompressionMode.Compress, true);
gzip.Write(data, 0, data.Length);
gzip.Close();
return output.ToArray();
}
public static byte[] Decompress(byte[] data) {
MemoryStream input = new MemoryStream();
input.Write(data, 0, data.Length);
input.Position = 0;
GZipStream gzip = new GZipStream(input,
CompressionMode.Decompress, true);
MemoryStream output = new MemoryStream();
byte[] buff = new byte[64];
int read = -1;
read = gzip.Read(buff, 0, buff.Length);
while(read > 0) {
output.Write(buff, 0, read);
read = gzip.Read(buff, 0, buff.Length);
}
gzip.Close();
return output.ToArray();
}
}
您需要将此类保存在一个 .cs 文件中,并将其放在 ASP.NET 应用程序的 App_Code 目录中,确保它包含在正确的自定义命名空间中(如果您不指定任何命名空间,该类将在内置的 ASP 命名空间中可用)。
压缩视图状态
现在,我们可以实际压缩页面的 ViewState 了。为此,我们必须重写 LoadPageStateFromPersistenceMedium 和 SavePageStateToPersistenceMedium 这两个方法。该代码仅使用一个附加隐藏字段 __VSTATE 来存储压缩的 ViewState。如您所见,通过查看页面的 HTML,__VIEWSTATE 字段为空,而我们的 __VSTATE 字段包含压缩后的 ViewState,以 Base64 编码。让我们看看代码。
public partial class MyPage : System.Web.UI.Page {
protected override object LoadPageStateFromPersistenceMedium() {
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = Compressor.Decompress(bytes);
LosFormatter formatter = new LosFormatter();
return formatter.Deserialize(Convert.ToBase64String(bytes));
}
protected override void SavePageStateToPersistenceMedium(object viewState) {
LosFormatter formatter = new LosFormatter();
StringWriter writer = new StringWriter();
formatter.Serialize(writer, viewState);
string viewStateString = writer.ToString();
byte[] bytes = Convert.FromBase64String(viewStateString);
bytes = Compressor.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
}
// The rest of your code here...
}
在第一种方法中,我们只是从 Base64 解码,解压缩和反序列化 __VSTATE 的内容,并将其返回给运行时。在第二种方法中,我们执行相反的操作:在 Base64 中序列化、压缩和编码。然后将 Base64 字符串保存到 __VSTATE 隐藏字段中。 LosFormatter 对象执行序列化和反序列化任务。
您可能还想创建一个新类,例如 CompressedPage,它继承自 System.Web.UI.Page,您在其中重写两个方法,然后从该类继承您的页面,例如 MyPage : CompressedPage。请记住,.NET 只有单一继承,通过这种方式,您“花费”了唯一的继承机会来使用 ViewState 压缩。另一方面,在每个类中重写这两个方法是浪费时间,因此您必须选择最适合您需要的方法。
以上内容由 Dario Solera 在 codeproject 上首次发布。
http://www.codeproject.com/Articles/14733/ViewState-Compression