In my previous post about Moving View State to Bottom of the Form I touched on one way to do some Search Engine Optimization in ASP.NET WebForms. Another thing you can do is to compress large View States on a page.

All the code in this article should be put in a class inheriting from System.Web.UI.Page. Like a page's Code-behind file or your own PageBase-class.

First we need some common logic for both loading and saving a compressed View State, the name of the hidden field to use.

private const string ViewStateFieldName = "SEOVIEWSTATE";

We start with the loading-part, where you see the use of my implementation of the CompressionHelper-class, which simplifies compression. It also solves the issue with DeflateStream and GZipStream inflating already compressed data, which is resolved in .NET Framework 4.

protected override object LoadPageStateFromPersistenceMedium() {
    return LoadCompressedPageState();
}

private object LoadCompressedPageState() {
    string viewState = Request.Form[ViewStateFieldName];
    if(string.IsNullOrEmpty(viewState)) {
        return string.Empty;
    }

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

    bool isCompressed = Convert.ToBoolean(Convert.ToInt32(viewState.Substring(0, 1)));
    if(isCompressed) {
        bytes = CompressionHelper.Decompress(bytes);
    }

    string decompressedBase64 = Convert.ToBase64String(bytes);

    ObjectStateFormatter formatter = new ObjectStateFormatter();
    return formatter.Deserialize(decompressedBase64);
}

We then move on to the implementation of saving the page's state.

protected override void SavePageStateToPersistenceMedium(object state) {
    SaveCompressedPageState(state);
}

private void SaveCompressedPageState(object state) {
    byte[] viewStateBytes;
    using(MemoryStream stream = new MemoryStream()) {
        ObjectStateFormatter formatter = new ObjectStateFormatter();
        formatter.Serialize(stream, state);
        viewStateBytes = stream.ToArray();
    }

    byte[] compressed;
    bool successfulCompress = CompressionHelper.TryCompress(viewStateBytes, out compressed);
    string compressedBase64 =
        Convert.ToInt32(successfulCompress) + Convert.ToBase64String(compressed);

    ClientScript.RegisterHiddenField(ViewStateFieldName, compressedBase64);
}

So the summary is that this will compress the View State of an ASP.NET WebForms page, if the View State is large enough. Otherwise it will just keep it the way it is.