Click here to Skip to main content
15,867,750 members
Articles / Web Development / ASP.NET
Alternative
Article

Compress ViewState with Deflate (C# ASP.NET)

Rate me:
Please Sign up or sign in to vote.
4.91/5 (7 votes)
7 Jun 2014CPOL2 min read 29.9K   17   7
Compress ViewState by using DeflatStream to reduce bandwidth.

Below are some of the earliest source that I can find about compressing ViewState:

30 Mar 2005, Scott Hanselman - Zipping/Compressing ViewState in ASP.NET (VB.NET)
Scott introduced a 3rd party tool - SharpZipLib, to perform the compression.
A C# version by Ingenium Llc (22 May 2013).

10 Jul 2006, Dario Solera - ViewState Compression
Dario demonstrated the code by using GZipStream to compress ViewState. He also mentioned Deflate as another option to compress ViewState.

On 8 Dec 2006, Mads Kristensen has perform a performance test between GZipStream and Deflate (GZip vs. Deflate – Compression and Performance) and he measured the Deflate is 41% faster than GZip.

Since there is no one yet presented the code of using Deflate to compress ViewState, I share it here. Maybe someone else had already shared it, but, however, the guides that I get are mostly showing GZipStream.

Sample Code: Compressing ViewState with Deflate

As usual, we intercept the handling of ViewState by overriding two public virtual method:

C#
public class BasePage : System.Web.UI.Page
{
    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 = Compress(bytes);
        ClientScript.RegisterHiddenField("__VIEWSTATE__", Convert.ToBase64String(bytes));
    }

    protected override object LoadPageStateFromPersistenceMedium()
    {
        string viewState = Request.Form["__VIEWSTATE__"];
        byte[] bytes = Convert.FromBase64String(viewState);
        bytes = Decompress(bytes);
        LosFormatter formatter = new LosFormatter();
        return formatter.Deserialize(Convert.ToBase64String(bytes));
    }
}

The compression part with Deflate:

C#
using System.IO;
using System.IO.Compression;
C#
public byte[] Compress(byte[] data)
{
    MemoryStream output = new MemoryStream();
    using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
    {
        dstream.Write(data, 0, data.Length);
    }
    return output.ToArray();
}

public byte[] Decompress(byte[] data)
{
    MemoryStream input = new MemoryStream(data);
    MemoryStream output = new MemoryStream();
    using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
    {
        dstream.CopyTo(output);
    }
    return output.ToArray();
}

Inherit all your WebForms with this class. Example:

C#
public partial class WebForm1 : BasePage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

ClientScript.RegisterHiddenField Only Works For Normal Postback

Retrieved from Viewstate compression – the right way (July 27, 2010 — Tudor Carean)

ClientScript.RegisterHiddenField() only works for normal postbacks. He presented the fix by replacing the original call to RegisterHiddenField with:

C#
System.Web.UI.ScriptManager sm = System.Web.UI.ScriptManager.GetCurrent(this);
if (sm != null && sm.IsInAsyncPostBack)
    System.Web.UI.ScriptManager.RegisterHiddenField(this, "__VIEWSTATE__", vState);
else
    Page.ClientScript.RegisterHiddenField("__VIEWSTATE__", vState);

Not Working Properly in UserControl

However, this implementation of custom compression explained above will not work properly too in UserControl, Tudo Carean has written a new class to replace the standard PageStatePersister which is one of the property of System.Web.UI.Page that defines the behavior of ViewState. 

Therefore, the new implementation of ViewState compression will be something like this:

C#
public class BasePage : Page
{
    private ViewStateCompressor _viewStateCompressor;
 
    public BasePage(): base()
    {
        _viewStateCompressor = new ViewStateCompressor(this);
    }
 
    protected override PageStatePersister PageStatePersister
    {
        get
        {
            return _viewStateCompressor;
        }
    }
}

This is the new written PageStatePersister. Tudo Carean uses GZip in his original code, I replaced GZip with Deflate:

C#
public class ViewStateCompressor : PageStatePersister
{
    public ViewStateCompressor(Page page)
        : base(page)
    {
    }

    private LosFormatter _stateFormatter;

    protected new LosFormatter StateFormatter
    {
        get
        {
            if (this._stateFormatter == null)
            {
                this._stateFormatter = new LosFormatter();
            }
            return this._stateFormatter;
        }
    }

    public override void Save()
    {
        using (StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture))
        {
            StateFormatter.Serialize(writer, new Pair(base.ViewState, base.ControlState));
            byte[] bytes = Convert.FromBase64String(writer.ToString());

            bytes = Compress(bytes);

            ScriptManager.RegisterHiddenField(Page, "__PIT", Convert.ToBase64String(bytes));
        }
    }

    public override void Load()
    {
        byte[] bytes = Convert.FromBase64String(base.Page.Request.Form["__PIT"]);

        bytes = Decompress(bytes);

        Pair p = ((Pair)(StateFormatter.Deserialize(Convert.ToBase64String(bytes))));
        base.ViewState = p.First;
        base.ControlState = p.Second;
    }
}

According to him, this new implementation works well in AJAX scenario and UserControl.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Other Other
Programming is an art.

Comments and Discussions

 
QuestionCan save compressed viewstate outside aspx webpage Pin
M. Salah AbdAllah9-Dec-14 3:47
professionalM. Salah AbdAllah9-Dec-14 3:47 
AnswerRe: Can save compressed viewstate outside aspx webpage Pin
adriancs9-Dec-14 13:36
mvaadriancs9-Dec-14 13:36 
GeneralRe: Can save compressed viewstate outside aspx webpage Pin
M. Salah AbdAllah29-Dec-14 22:42
professionalM. Salah AbdAllah29-Dec-14 22:42 
GeneralRe: Can save compressed viewstate outside aspx webpage Pin
M. Salah AbdAllah29-Dec-14 22:51
professionalM. Salah AbdAllah29-Dec-14 22:51 
QuestionNice Article Pin
Jack Tang 447808330-Jun-14 4:02
Jack Tang 447808330-Jun-14 4:02 
QuestionThe outcome Pin
abdurahman ibn hattab10-Jun-14 3:14
abdurahman ibn hattab10-Jun-14 3:14 
QuestionAbout ASP.Net Pin
Velma W. Johnson4-Jun-14 0:57
Velma W. Johnson4-Jun-14 0:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.