Click here to Skip to main content
Click here to Skip to main content
Alternative Article
Go to top

Compress ViewState with Deflate (C# ASP.NET)

, 7 Jun 2014
Rate this:
Please Sign up or sign in to vote.
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:

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:

using System.IO;
using System.IO.Compression;
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:

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:

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:

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:

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)

Share

About the Author

adriancs
Software Developer
Malaysia Malaysia
Writing programs is an art.

Comments and Discussions

 
QuestionNice Article PinmemberJack Tang 447808330-Jun-14 4:02 
QuestionThe outcome Pinmemberabdurahman ibn hattab10-Jun-14 3:14 
QuestionAbout ASP.Net PinmemberVelma W. Johnson4-Jun-14 0:57 
There are several techniques available to reduce ASP.NET page output size.
 

 

Cert4Prep Questions Answers

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140926.1 | Last Updated 7 Jun 2014
Article Copyright 2014 by adriancs
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid