重写PageStatePersister属性 自定义压缩方法来减小ViewState大小来优化页面加载时间
//在正常情况下,页面都会自动调用默认的LosFormatter来压缩ViewState. 但是我们可以实现PageStatePersister类。
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Compression;
/// <summary>
/// CompressPageStatePersister 的摘要说明
/// </summary>
public class CompressPageStatePersister:PageStatePersister
{
//页面状态保存在页面中的字段名
private const string STATEKEY = "____VIEWSTATE";
public CompressPageStatePersister(Page page) : base(page) { }
public override void Load()
{
//取得保存到客户端的状态内容
string postbackState = Page.Request.Form[STATEKEY];
if (!string.IsNullOrEmpty(postbackState))
{
//解压,反序列化状态,
//ASP.NET2.0中的页面状态包括视图状态和控件状态两部分
Pair statePair = (Pair)GZipCompress.Decompress(postbackState);
if (!Page.EnableViewState)
{
ViewState = null;
}
else
{
ViewState = statePair.First;
}
ControlState = statePair.Second;
}
}
public override void Save()
{
if (!Page.EnableViewState)
{
ViewState = null;
}
if (ViewState != null || ControlState != null)
{
string stateString;
Pair statePair = new Pair(ViewState, ControlState);
//序列化并压缩状态
stateString = GZipCompress.Compress(statePair);
Page.ClientScript.RegisterHiddenField(STATEKEY, stateString);
}
}
}
public class GZipTest
{
public static int ReadAllBytesFromStream(Stream stream, byte[] buffer)
{
// Use this method is used to read all bytes from a stream.
int offset = 0;
int totalCount = 0;
while (true)
{
int bytesRead = stream.Read(buffer, offset, 100);
if (bytesRead <= 0)
{
break;
}
offset += bytesRead;
totalCount += bytesRead;
}
return totalCount;
}
public static bool CompareData(byte[] buf1, int len1, byte[] buf2, int len2)
{
// Use this method to compare data from two different buffers.
if (len1 != len2)
{
Console.WriteLine("Number of bytes in two buffer are different {0}:{1}", len1, len2);
return false;
}
for (int i = 0; i < len1; i++)
{
if (buf1[i] != buf2[i])
{
Console.WriteLine("byte {0} is different {1}|{2}", i, buf1[i], buf2[i]);
return false;
}
}
Console.WriteLine("All bytes compare.");
return true;
}
public static void GZipCompressDecompress(string filename)
{
Console.WriteLine("Test compression and decompression on file {0}", filename);
FileStream infile;
try
{
// Open the file as a FileStream object.
infile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] buffer = new byte[infile.Length];
// Read the file to ensure it is readable.
int count = infile.Read(buffer, 0, buffer.Length);
if (count != buffer.Length)
{
infile.Close();
Console.WriteLine("Test Failed: Unable to read data from file");
return;
}
infile.Close();
MemoryStream ms = new MemoryStream();
// Use the newly created memory stream for the compressed data.
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true);
Console.WriteLine("Compression");
compressedzipStream.Write(buffer, 0, buffer.Length);
// Close the stream.
compressedzipStream.Close();
Console.WriteLine("Original size: {0}, Compressed size: {1}", buffer.Length, ms.Length);
// Reset the memory stream position to begin decompression.
ms.Position = 0;
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
Console.WriteLine("Decompression");
byte[] decompressedBuffer = new byte[buffer.Length + 100];
// Use the ReadAllBytesFromStream to read the stream.
int totalCount = GZipTest.ReadAllBytesFromStream(zipStream, decompressedBuffer);
Console.WriteLine("Decompressed {0} bytes", totalCount);
if (!GZipTest.CompareData(buffer, buffer.Length, decompressedBuffer, totalCount))
{
Console.WriteLine("Error. The two buffers did not compare.");
}
zipStream.Close();
} // end try
catch (InvalidDataException)
{
Console.WriteLine("Error: The file being read contains invalid data.");
}
catch (FileNotFoundException)
{
Console.WriteLine("Error:The file specified was not found.");
}
catch (ArgumentException)
{
Console.WriteLine("Error: path is a zero-length string, contains only white space, or contains one or more invalid characters");
}
catch (PathTooLongException)
{
Console.WriteLine("Error: The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("Error: The specified path is invalid, such as being on an unmapped drive.");
}
catch (IOException)
{
Console.WriteLine("Error: An I/O error occurred while opening the file.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Error: path specified a file that is read-only, the path is a directory, or caller does not have the required permissions.");
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Error: You must provide parameters for MyGZIP.");
}
}
public static void Main(string[] args)
{
string usageText = "Usage: MYGZIP <inputfilename>";
//If no file name is specified, write usage text.
if (args.Length == 0)
{
Console.WriteLine(usageText);
}
else
{
if (File.Exists(args[0]))
GZipCompressDecompress(args[0]);
}
}
}
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.IO.Compression;
/// <summary>
/// CompressPageStatePersister 的摘要说明
/// </summary>
public class CompressPageStatePersister:PageStatePersister
{
//页面状态保存在页面中的字段名
private const string STATEKEY = "____VIEWSTATE";
public CompressPageStatePersister(Page page) : base(page) { }
public override void Load()
{
//取得保存到客户端的状态内容
string postbackState = Page.Request.Form[STATEKEY];
if (!string.IsNullOrEmpty(postbackState))
{
//解压,反序列化状态,
//ASP.NET2.0中的页面状态包括视图状态和控件状态两部分
Pair statePair = (Pair)GZipCompress.Decompress(postbackState);
if (!Page.EnableViewState)
{
ViewState = null;
}
else
{
ViewState = statePair.First;
}
ControlState = statePair.Second;
}
}
public override void Save()
{
if (!Page.EnableViewState)
{
ViewState = null;
}
if (ViewState != null || ControlState != null)
{
string stateString;
Pair statePair = new Pair(ViewState, ControlState);
//序列化并压缩状态
stateString = GZipCompress.Compress(statePair);
Page.ClientScript.RegisterHiddenField(STATEKEY, stateString);
}
}
}
public class GZipTest
{
public static int ReadAllBytesFromStream(Stream stream, byte[] buffer)
{
// Use this method is used to read all bytes from a stream.
int offset = 0;
int totalCount = 0;
while (true)
{
int bytesRead = stream.Read(buffer, offset, 100);
if (bytesRead <= 0)
{
break;
}
offset += bytesRead;
totalCount += bytesRead;
}
return totalCount;
}
public static bool CompareData(byte[] buf1, int len1, byte[] buf2, int len2)
{
// Use this method to compare data from two different buffers.
if (len1 != len2)
{
Console.WriteLine("Number of bytes in two buffer are different {0}:{1}", len1, len2);
return false;
}
for (int i = 0; i < len1; i++)
{
if (buf1[i] != buf2[i])
{
Console.WriteLine("byte {0} is different {1}|{2}", i, buf1[i], buf2[i]);
return false;
}
}
Console.WriteLine("All bytes compare.");
return true;
}
public static void GZipCompressDecompress(string filename)
{
Console.WriteLine("Test compression and decompression on file {0}", filename);
FileStream infile;
try
{
// Open the file as a FileStream object.
infile = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] buffer = new byte[infile.Length];
// Read the file to ensure it is readable.
int count = infile.Read(buffer, 0, buffer.Length);
if (count != buffer.Length)
{
infile.Close();
Console.WriteLine("Test Failed: Unable to read data from file");
return;
}
infile.Close();
MemoryStream ms = new MemoryStream();
// Use the newly created memory stream for the compressed data.
GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true);
Console.WriteLine("Compression");
compressedzipStream.Write(buffer, 0, buffer.Length);
// Close the stream.
compressedzipStream.Close();
Console.WriteLine("Original size: {0}, Compressed size: {1}", buffer.Length, ms.Length);
// Reset the memory stream position to begin decompression.
ms.Position = 0;
GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress);
Console.WriteLine("Decompression");
byte[] decompressedBuffer = new byte[buffer.Length + 100];
// Use the ReadAllBytesFromStream to read the stream.
int totalCount = GZipTest.ReadAllBytesFromStream(zipStream, decompressedBuffer);
Console.WriteLine("Decompressed {0} bytes", totalCount);
if (!GZipTest.CompareData(buffer, buffer.Length, decompressedBuffer, totalCount))
{
Console.WriteLine("Error. The two buffers did not compare.");
}
zipStream.Close();
} // end try
catch (InvalidDataException)
{
Console.WriteLine("Error: The file being read contains invalid data.");
}
catch (FileNotFoundException)
{
Console.WriteLine("Error:The file specified was not found.");
}
catch (ArgumentException)
{
Console.WriteLine("Error: path is a zero-length string, contains only white space, or contains one or more invalid characters");
}
catch (PathTooLongException)
{
Console.WriteLine("Error: The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.");
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("Error: The specified path is invalid, such as being on an unmapped drive.");
}
catch (IOException)
{
Console.WriteLine("Error: An I/O error occurred while opening the file.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Error: path specified a file that is read-only, the path is a directory, or caller does not have the required permissions.");
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("Error: You must provide parameters for MyGZIP.");
}
}
public static void Main(string[] args)
{
string usageText = "Usage: MYGZIP <inputfilename>";
//If no file name is specified, write usage text.
if (args.Length == 0)
{
Console.WriteLine(usageText);
}
else
{
if (File.Exists(args[0]))
GZipCompressDecompress(args[0]);
}
}
}
//GzipCompress
using System;
using System.IO;
using System.IO.Compression;
using System.Web.UI;
/// <summary>
/// GZipCompress 的摘要说明
/// </summary>
public class GZipCompress
{
//序列化工具,LosFormatter是页面默认的序列器
private static LosFormatter _formatter = new LosFormatter();
/// <summary>
/// 解压并反序列化状态内容
/// </summary>
/// <param name="stateString">从客户端取回的页面状态字符串</param>
/// <returns>还原后的页面状态Pair对象</returns>
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 = 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);
}
/// <summary>
/// 序列化并压缩状态内容
/// </summary>
/// <param name="state">页面状态</param>
/// <returns>结果字符串</returns>
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();
//将压缩结果转成Base64字符串,以便存到页面中
stateString = Convert.ToBase64String(buffer);
return stateString;
}
}
using System.IO;
using System.IO.Compression;
using System.Web.UI;
/// <summary>
/// GZipCompress 的摘要说明
/// </summary>
public class GZipCompress
{
//序列化工具,LosFormatter是页面默认的序列器
private static LosFormatter _formatter = new LosFormatter();
/// <summary>
/// 解压并反序列化状态内容
/// </summary>
/// <param name="stateString">从客户端取回的页面状态字符串</param>
/// <returns>还原后的页面状态Pair对象</returns>
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 = 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);
}
/// <summary>
/// 序列化并压缩状态内容
/// </summary>
/// <param name="state">页面状态</param>
/// <returns>结果字符串</returns>
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();
//将压缩结果转成Base64字符串,以便存到页面中
stateString = Convert.ToBase64String(buffer);
return stateString;
}
}
//测试
public partial class Pages_Default : System.Web.UI.Page
{
#region
CompressPageStatePersister _pageStatePersister = null;
protected override PageStatePersister PageStatePersister
{
get
{
if (_pageStatePersister == null)
{
_pageStatePersister = new CompressPageStatePersister(this);
}
return _pageStatePersister;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataBind();
}
}
{
#region
CompressPageStatePersister _pageStatePersister = null;
protected override PageStatePersister PageStatePersister
{
get
{
if (_pageStatePersister == null)
{
_pageStatePersister = new CompressPageStatePersister(this);
}
return _pageStatePersister;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
GridView1.DataBind();
}
}