How to compress ViewState In ASP.NET
Http is a stateless protocol. Hence the ‘page-state-information’ is not saved between postbacks. In ASP.NET, viewstate is the means of storing the state of server side controls between postbacks. It contains a snapshot of the contents of a page. The information is stored in HTML hidden fields.
The viewstate is quiet handy in most cases as it does a lot of work for you in saving the state of controls. However it comes with a cost. If your page contains a lot of controls holding a large amount of data, you can imagine the load when this data is transferred to and from the browser on each postback. It gradually increases the size of your page, thereby leading to performance issues. Well you can get around this problem by disabling viewstate for controls, where maintaining state is not required (EnableViewState=false). However, in scenarios, where maintaining the state of controls is required, compressing viewstate helps improve performance.
Using System.IO.Compression
In ASP.NET 1.1, developers used custom compression tools like ICSharpCode.SharpZipLib to compress viewstate. ASP.NET 2.0 provides us with the System.IO.Compression namespace, which contains classes with functionality to compress and decompress streams. This namespace contains two classes called DeflateStream and GZipStream that provides methods and properties to compress and decompress streams.
Compressing/Decompressing using GZipStream
The compression functionality in GZipStream is exposed as a stream. In the code displayed below, we will create a class called ViewStateCompressor that contains two methods :
Compress(byte[] array) - Accepts a decompressed bytearray, compresses it and returns a compressed bytearray.
Decompress(byte[] array) – Accepts compressed bytearray, decompresses it and returns a decompressed bytearray.
The code has been commented to help you understand each method.
using System;
using System.Data;
using System.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;
///<summary>
/// Summary description for ViewStateCompressor
///</summary>
public class ViewStateCompressor
{
public ViewStateCompressor()
{
//
// TODO: Add constructor logic here
//
}
public static byte[] CompressViewState(byte[] uncompData)
{
using (MemoryStream mem = new MemoryStream())
{
CompressionMode mode = CompressionMode.Compress;
// Use the newly created memory stream for the compressed data.
using (GZipStream gzip = new GZipStream(mem, mode, true))
{
//Writes compressed byte to the underlying
//stream from the specified byte array.
gzip.Write(uncompData, 0, uncompData.Length);
}
return mem.ToArray();
}
}
public static byte[] DecompressViewState(byte[] compData)
{
GZipStream gzip;
using (MemoryStream inputMem = new MemoryStream())
{
inputMem.Write(compData, 0, compData.Length);
// Reset the memory stream position to begin decompression.
inputMem.Position = 0;
CompressionMode mode = CompressionMode.Decompress;
gzip = new GZipStream(inputMem, mode, true);
using (MemoryStream outputMem = new MemoryStream())
{
// Read 1024 bytes at a time
byte[] buf = new byte[1024];
int byteRead = -1;
byteRead = gzip.Read(buf, 0, buf.Length);
while (byteRead > 0)
{
//write to memory stream
outputMem.Write(buf, 0, byteRead);
byteRead = gzip.Read(buf, 0, buf.Length);
}
gzip.Close();
return outputMem.ToArray();
}
}
}
}
Utilizing the ViewStateCompressor class
Once we have created the functionality of compressing and decompressing viewstate, its time to use this functionality in our webpages. For this, create a CustomPage which inherits from System.Web.UI.Page. In the CustomPage, you will need to override the LoadPageStateFromPersistenceMedium() and SavePageStateToPersistenceMedium() to serialize and deserialize viewstate. We require this customization because we are compressing the viewstate. All the other web pages in the application will inherit from this BasePage.
The LoadPageStateFromPersistenceMedium() method has been overridden here to decompress the bytes stored in hidden field “_CustomViewState”. The steps performed are as follows :
· The compressed viewstate stored in this field is encoded as Base64 string.
· The Convert.FromBase64String(viewState) converts it into byte array.
· It’s time to call the DecompressViewState() method we created earlier.
· This method returns a bytearray containing decompressesed data which is converted back to Base64 string.
· Finally the LosFormatter class is used to deserialize the view state.
The SavePageStateToPersistenceMedium() method accepts a ViewState object. The Serialize() method of the LosFormatter class accepts a stream and the viewstate object. If you have already observed, we are performing a reverse operation of what we did in the LoadPageStateFromPersistenceMedium() method. We will first serialize, compress and then encode data in Base64. This Base64 string is then saved into the “_CustomViewState” hidden field.
The code has been given below :
using System;
using System.Data;
using System.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;
///<summary>
/// Summary description for CustomPage
///</summary>
public partial class CustomPage : Page
{
public CustomPage()
{
//
// TODO: Add constructor logic here
//
}
// Serialize view state
protected override void SavePageStateToPersistenceMedium(object pageViewState)
{
LosFormatter losformatter = new LosFormatter();
StringWriter sw = new StringWriter();
losformatter.Serialize(sw, pageViewState);
string viewStateString = sw.ToString();
byte[] b = Convert.FromBase64String(viewStateString);
b = ViewStateCompressor.CompressViewState(b);
ClientScript.RegisterHiddenField("__CUSTOMVIEWSTATE", Convert.ToBase64String(b));
}
// Deserialize view state
protected override object LoadPageStateFromPersistenceMedium()
{
string custState = Request.Form["__CUSTOMVIEWSTATE"];
byte[] b = Convert.FromBase64String(custState);
b = ViewStateCompressor.DecompressViewState(b);
LosFormatter losformatter = new LosFormatter();
return losformatter.Deserialize(Convert.ToBase64String(b));
}
}
There you go!! Use these classes and hopefully your ViewState size will be reduced by 30-40%.
References
There are a number of good resources I referred to for this article. A few of them are:
http://www.dotnetbips.com/articles/22d33d11-1a75-42c8-bbf6-ca1a345d3fcf.aspx
http://www.codeproject.com/aspnet/ViewStateCompression.asp
http://www.eggheadcafe.com/articles/20040613.asp
http://msdn2.microsoft.com
Conclusion
This article introduced you to a new namespace System.IO.Compression in ASP.NET 2.0. We went through the classes provided in this namespace. The GzipStream class contains functionality to compress and decompress streams. We used it to compress and decompress viewstate to improve performance of our web applications. I hope this article was informative and I thank you for viewing it.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of
DotNetCurry,
DNC Magazine for Developers,
SQLServerCurry and
DevCurry. He has also authored a couple of books
51 Recipes using jQuery with ASP.NET Controls and
The Absolutely Awesome jQuery CookBook.
Suprotim has received the prestigious Microsoft MVP award for ten consecutive times. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.
Get in touch with him on Twitter @suprotimagarwal or at LinkedIn