ASP.NET Viewstate Compression

ASP.NET Web Forms

A few days back I came across a issue in a ASP.NET project which I was asked to optimized.

Dealing with viewstate is not a easy task, specially when you have lots of controls in your form.

Here my project was going to be used over internet at very slow speed.

After measuring my post and response size I found that it was somewhere around 100kb and that was annoying.

Now I had few options in my mind to go ahead with first to generate control at client end using javascript/jquery which was not feasible because I had many user controls which had killer GridView and DropDowns and a few other control which live on viewstate, second was to disable viewstate which I tried but end up with many runtime error.

Going out of time I had to act quick.

I end up reading this article

Zipping/Compressing ViewState in ASP.NET

And implementing the tweak in my project.

Here it goes

First

Override base class i.e. Page class

Method n function

SavePageStateToPersistenceMedium and LoadPageStateFromPersistenceMedium

As the name says SavePageStateToPersistenceMedium save the view state data which we get as a parameter to this method.

LoadPageStateFromPersistenceMedium retrives the viewstate from the hidden field and return the data.

private readonly ObjectStateFormatter _objectStateFormatter =new ObjectStateFormatter();

protected override void SavePageStateToPersistenceMedium(object viewState)

{

        byte[] viewStateArray;

        using (MemoryStream memoryStream = new MemoryStream())

        {

            _objectStateFormatter.Serialize(memoryStream, viewState);

            viewStateArray = memoryStream.ToArray();

        }

        ClientScript.RegisterHiddenField("__VIEWSTATE", Convert.ToBase64String(GZip.Compress(viewStateArray)));

}

protected override object LoadPageStateFromPersistenceMedium()

{

    string viewState = Request.Form["__VIEWSTATE"];

    byte[] bytes = Convert.FromBase64String(viewState);

    Stopwatch obj = new Stopwatch();

    obj.Start();

    bytes = Decompress(bytes);

    obj.Stop();

    return _objectStateFormatter.Deserialize(Convert.ToBase64String(bytes));

}

End result - no success.

Problem here was when i registered a hidden field with __VSTATE as id it didnt returned the viewstate (i.e. the control data after overriding LoadPageStateFromPersistenceMedium where __VSTATE had the data but didnt showed in the controls)
and when i saved the data to __VIEWSTATE which is the id of default viewstate hidden field in asp.net got this

"Invalid character in a Base-64 string.".

After a day of unsuccessful attempt I came across:

Viewstate Compression Issues [Resolved]

a work around.

private readonly ObjectStateFormatter _objectStateFormatter =new ObjectStateFormatter();

protected override void SavePageStateToPersistenceMedium(object viewState)

{

    byte[] viewStateArray;

    using (MemoryStream memoryStream = new MemoryStream())

    {

        _objectStateFormatter.Serialize(memoryStream, viewState);

        viewStateArray = memoryStream.ToArray();

    }

    base.SavePageStateToPersistenceMedium(Convert.ToBase64String(Compress(viewStateArray)));

    // ClientScript.RegisterHiddenField("__VIEWSTATE", Convert.ToBase64String(GZip.Compress(viewStateArray)));

}

protected override object LoadPageStateFromPersistenceMedium()

{

    string viewState = base.LoadPageStateFromPersistenceMedium().ToString();// Request.Form["__COMPRESSEDVIEWSTATE"];

    //string viewState = Request.Form["__VIEWSTATE"];

    byte[] bytes = Convert.FromBase64String(viewState);

    Stopwatch obj = new Stopwatch();

    obj.Start();

    bytes = Decompress(bytes);

    obj.Stop();

    return _objectStateFormatter.Deserialize(Convert.ToBase64String(bytes));

} 

Again no success.

Debugging i found the base.LoadPageStateFromPersistenceMedium returns a System.Web.UI.Pair and not string so simply casting that and looking for the viewstate solved my problem.

String viewState = ((System.Web.UI.Pair)base.LoadPageStateFromPersistenceMedium()).Second.ToString();

As the msdn article about ASP.NET Page Life Cycle

Understanding ASP.NET View State

Viewstate is loaded just after the init event

and saved between raise postback and render event.

Making these changes saved a lot of bandwith and time while loading and updating page.

Hope this helps you and sorts your problem if you come across this issue.