hi all,
found a nice little article explaining the benefits of overrriding the LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium methods to allow for compression of the viewstate. i've jigged it around and managed to get it to work globally across my beerhouse test site. basically, i only had to amend two classes in the App_Code folder (all additions in red if you prefer to just paste those sections in):
Globals.cs
BasePage.cs
here is the Globals.cs:
using System;
using System.Data;
using System.Configuration;
using System.Web.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;
namespace MB.TheBeerHouse
{
public static class Globals
{
// compression for viewstate (or any html perhaps)
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();
} // end viewstate compression
public readonly static TheBeerHouseSection Settings = (TheBeerHouseSection)WebConfigurationManager.GetSe ction("TheBeerHouse");
public static string ThemesSelectorID = "";
static Globals()
{
}
}
}
and here is the BasePage.cs (i've only included the new entries here as it was rather a long class in my app - again actual entries in red)
using System.IO;
namespace MB.TheBeerHouse.UI
{
public class BasePage : System.Web.UI.Page
{
// added to compress viewstate also in globals
protected override object LoadPageStateFromPersistenceMedium()
{
string viewState = Request.Form["__VSTATE"];
byte[] bytes = Convert.FromBase64String(viewState);
bytes = Globals.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 = Globals.Compress(bytes);
ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));
} // end viewstate additions
Hope it works as great for you as it is for me, average savings of 30-60%, which means a good speedy page load and less bandwidth useage!!
enjoy
[edit] as an aside, the bigger the viewstate, the bigger the savings. i just ran a few pages that had a viewstate size of 25k. this reduced to 9k with compression - so far so good!!
jimi
http://www.jamestollan.com