Click here to Skip to main content
12,298,927 members (51,161 online)
Click here to Skip to main content
Add your own
alternative version


161 bookmarked

ViewState Compression

, 10 Jul 2006 CPOL
Rate this:
Please Sign up or sign in to vote.
How to compress the ViewState of ASP.NET pages and save bandwidth.


Recently, I developed a huge ASP.NET page, with more than 30 controls. As we all know, it's a good idea to disable the ViewState for the controls that don't actually need it, say Literals or Labels. After doing that, I noticed that the hidden ViewState field was still a few KBs big. This is obviously a big problem for the users that still don't have a broadband connection, because uploading 40 KB to the server is really a bad issue, especially when they begin to click the "Submit" button again and again because they don't notice any response. So, after a few searches through the Internet, I built a simple solution to compress the ViewState and therefore save a rough 50% of the bandwidth. This post by Scott Hanselman has been particularly useful. Although it's possible to use external libraries to perform compression tasks, I think the better solution is to use the GZipStream or DeflateStream that the .NET Framework 2.0 includes.

Compressing and Decompressing Data in Memory

First of all, we need a way to compress and decompress an array of bytes in memory. I put together this simple static class that exposes two methods: Compress and Decompress. The two available classes, GZipStream and DeflateStream, according to MSDN, use the same algorithm, so it's irrelevant which one you choose.

The code below is really simple, and doesn't need further explanation:

using System.IO;
using System.IO.Compression;

public static class Compressor {

  public static byte[] Compress(byte[] data) {
    MemoryStream output = new MemoryStream();
    GZipStream gzip = new GZipStream(output, 
                      CompressionMode.Compress, true);
    gzip.Write(data, 0, data.Length);
    return output.ToArray();

  public static byte[] Decompress(byte[] data) {
    MemoryStream input = new MemoryStream();
    input.Write(data, 0, data.Length);
    input.Position = 0;
    GZipStream gzip = new GZipStream(input, 
                      CompressionMode.Decompress, true);
    MemoryStream output = new MemoryStream();
    byte[] buff = new byte[64];
    int read = -1;
    read = gzip.Read(buff, 0, buff.Length);
    while(read > 0) {
      output.Write(buff, 0, read);
      read = gzip.Read(buff, 0, buff.Length);
    return output.ToArray();

You need to save this class in a .cs file and put it in the App_Code directory of your ASP.NET application, making sure it's contained in the proper custom namespace (if you don't specify any namespace, the class will be available in the built-in ASP namespace).

Compressing the ViewState

Now, we can actually compress the ViewState of the page. To do that, we have to override the two methods LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium. The code simply uses an additional hidden field, __VSTATE, to store the compressed ViewState. As you can see, by viewing the HTML of the page, the __VIEWSTATE field is empty, while our __VSTATE field contains the compressed ViewState, encoded in Base64. Let's see the code.

public partial class MyPage : System.Web.UI.Page {

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

  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 = Compressor.Compress(bytes);
    ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes));

  // The rest of your code here...

In the first method, we just decode from Base64, decompress and deserialize the content of the __VSTATE, and return it to the runtime. In the second method, we perform the opposite operation: serialize, compress, and encode in Base64. The Base64 string is then saved into the __VSTATE hidden field. The LosFormatter object performs the serialization and deserialization tasks.

You may also want to create a new class, for example, CompressedPage, inheriting from System.Web.UI.Page, in which you override the two methods and then inherit your page from that class, for example MyPage : CompressedPage. Just remember that .NET has only single inheritance, and by following this way, you "spend" your only inheritance chance to use the ViewState compression. On the other hand, overriding the two methods in every class is a waste of time, so you have to choose the way that best fits your needs.

Performances and Conclusions

After a few tests, I noticed that the ViewState has been reduced from 38 KB to 17 KB, saving 44%. Supposing you have an average of 1 postback per minute per user, you could save more than 885 MB of bandwidth per month on every single user. That's an excellent result: you save bandwidth (and therefore money), and the user notices a shorter server response time.

I wanted to point out that this solution has a performance hit on the server's hardware. Compressing, decompressing, encoding, and decoding data is quite a heavy work for the server, so you have to balance the number of users with your CPU power and RAM.


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


About the Author

Dario Solera
Italy Italy
Software Development Manager working on IaaS cloud computing. Cloud believer, (former) entrepreneur, F1 addict.

Follow me at or on Twitter.

You may also be interested in...

Comments and Discussions

QuestionViewstate issue with SharePoint Pin
PiranF30-Dec-14 20:32
memberPiranF30-Dec-14 20:32 
QuestionHow do you do this with masterpages? Pin
olaleke11-Feb-14 0:39
memberolaleke11-Feb-14 0:39 
AnswerRe: How do you do this with masterpages? Pin
adriancs3-Jun-14 20:12
professionaladriancs3-Jun-14 20:12 
QuestionProblem!! Pin
Member 1005975420-Jun-13 7:04
memberMember 1005975420-Jun-13 7:04 
AnswerRe: Problem!! Pin
Member 1005975420-Jun-13 7:46
memberMember 1005975420-Jun-13 7:46 
GeneralMy vote of 5 Pin
amadou daffe5-Dec-12 7:56
memberamadou daffe5-Dec-12 7:56 
QuestionNot sure that problem exists in a first place Pin
George20142-Sep-12 19:05
memberGeorge20142-Sep-12 19:05 
AnswerRe: Not sure that problem exists in a first place Pin
boros2419-Sep-12 6:30
memberboros2419-Sep-12 6:30 
AnswerRe: Not sure that problem exists in a first place Pin
amit@123456710-Dec-12 21:45
memberamit@123456710-Dec-12 21:45 
GeneralMy vote of 5 Pin
Carlos Mattos (MVP)14-Aug-12 9:18
memberCarlos Mattos (MVP)14-Aug-12 9:18 
QuestionNaming & performance Pin
Malay Thakershi1-Aug-12 12:43
memberMalay Thakershi1-Aug-12 12:43 
GeneralMy vote of 5 Pin
lunabi668-Feb-11 2:27
memberlunabi668-Feb-11 2:27 
GeneralMy vote of 5 Pin
E.F. Nijboer22-Oct-10 12:34
memberE.F. Nijboer22-Oct-10 12:34 
QuestionCompression generates even bigger viewstate, why? Pin
jrbosch4-Feb-10 12:21
memberjrbosch4-Feb-10 12:21 
AnswerRe: Compression generates even bigger viewstate, why? Pin
ShadowDanser16-Jan-11 3:13
memberShadowDanser16-Jan-11 3:13 
GeneralOptimize code Pin
truongpham17-Oct-09 7:07
membertruongpham17-Oct-09 7:07 
GeneralRe: Optimize code Pin
E.F. Nijboer22-Oct-10 12:33
memberE.F. Nijboer22-Oct-10 12:33 
QuestionExcellent!!! but have some problems with UserControls Pin
inharry17-Sep-09 10:33
memberinharry17-Sep-09 10:33 
GeneralSuperb! Pin
kjerolran5-Mar-09 10:23
memberkjerolran5-Mar-09 10:23 
Generaldoubt in above article Pin
Maha_M15-Jun-08 5:40
memberMaha_M15-Jun-08 5:40 
QuestionMemory leak? Pin
lrwilson4-Jun-08 3:59
memberlrwilson4-Jun-08 3:59 
AnswerRe: Memory leak? Pin
Dario Solera7-Jun-08 6:12
memberDario Solera7-Jun-08 6:12 
GeneralCompression and Ajax Pin
mdmasonmbcs14-Apr-08 5:22
membermdmasonmbcs14-Apr-08 5:22 
GeneralRe: Compression and Ajax Pin
Tim McCurdy14-Jan-09 2:53
memberTim McCurdy14-Jan-09 2:53 
That's because you haven't taken into account "AsyncPostBacks". During every PostBack you need to Compress / Decompress the ViewState. This needs special handling during an AsyncPostBack where MS Ajax is involved. If you're using a differt Ajax Framework, sorry, I can't help you, but it's the same concept. You don't need to modify you Compress / Decompress routines, just the Restore/Save PageStateToPersistanceMedium.

Notice the bolded text in the "SavePageStateToPersistenceMedium" method. During an AsyncPostBack you need to re-register the HiddenField, however, you cannot simply just do this the same way. If you're in an AsyncPostBack, you need to use the ScriptManager methods to do this. If you're just in the first PageLoad or subsequent PostBacks, then using the ClientScript is fine.

/// <summary>
/// Loads the ViewState from the persistence medium
/// </summary>
protected override object LoadPageStateFromPersistenceMedium()
	try {
		string compression = ConfigurationManager.AppSettings["viewStateCompression"];
		if (string.IsNullOrEmpty(compression)) compression = "true";
		if (bool.Parse(compression)) {
			string viewState = Request.Form["__VSTATE"];
			if (viewState.EndsWith(",")) viewState = viewState.Substring(0, viewState.Length - 1);
			byte[] bytes = Convert.FromBase64String(viewState);
					bytes = BasePage.Decompress(bytes);
			viewState = Convert.ToBase64String(bytes);
			if (string.IsNullOrEmpty(viewState)) return null;
			LosFormatter formatter = new LosFormatter();
			return formatter.Deserialize(viewState);
			return base.LoadPageStateFromPersistenceMedium();
	catch (Exception) { throw; }
/// <summary>
/// Saves the ViewState from the persistence medium
/// </summary>
protected override void SavePageStateToPersistenceMedium(object state)
	StringWriter writer = new StringWriter();
	try {
		string compression = ConfigurationManager.AppSettings["viewStateCompression"];
		if (string.IsNullOrEmpty(compression)) compression = "true";
		if (bool.Parse(compression)) {
			LosFormatter formatter = new LosFormatter();
			formatter.Serialize(writer, state);
			string vState = writer.ToString();
			byte[] bytes = Convert.FromBase64String(vState);
			bytes = BasePage.Compress(bytes);
			vState = Convert.ToBase64String(bytes);
			System.Web.UI.ScriptManager sm = System.Web.UI.ScriptManager.GetCurrent(this);
			if (sm != null && sm.IsInAsyncPostBack)
				System.Web.UI.ScriptManager.RegisterHiddenField(this, "__VSTATE", vState);
				Page.ClientScript.RegisterHiddenField("__VSTATE", vState);
	catch (Exception) { throw; }
	finally {
		if (writer != null) { writer.Dispose(); writer = null; }

GeneralRe: Compression and Ajax Pin
Mninawa18-Aug-10 3:25
memberMninawa18-Aug-10 3:25 
GeneralRe: Compression and Ajax Pin
Tim McCurdy18-Aug-10 3:59
memberTim McCurdy18-Aug-10 3:59 
Generalgood stuff Pin
mrkyle28-Feb-08 18:39
membermrkyle28-Feb-08 18:39 
GeneralExcellent Article..!! Pin
Sujith John Thomas21-Jul-07 2:18
memberSujith John Thomas21-Jul-07 2:18 
GeneralAnother way [modified] Pin
boros2422-Feb-07 3:13
memberboros2422-Feb-07 3:13 
GeneralRe: Another way Pin
Munsifali Rashid28-Oct-07 11:02
memberMunsifali Rashid28-Oct-07 11:02 
GeneralRe: Another way Pin
Fahad Azeem25-Apr-08 5:47
memberFahad Azeem25-Apr-08 5:47 
GeneralASP.NET AJAX 1.0 Problem Pin
lookaround15-Feb-07 2:48
memberlookaround15-Feb-07 2:48 
GeneralRe: ASP.NET AJAX 1.0 Problem Pin
DAJG10-Jul-07 8:06
memberDAJG10-Jul-07 8:06 
GeneralRe: ASP.NET AJAX 1.0 Problem Pin
uyildir11-Nov-07 10:08
memberuyildir11-Nov-07 10:08 
GeneralRe: ASP.NET AJAX 1.0 Problem Pin
CoolVini6-Oct-08 23:16
memberCoolVini6-Oct-08 23:16 
GeneralRe: ASP.NET AJAX 1.0 Problem Pin
kjerolran5-Mar-09 10:02
memberkjerolran5-Mar-09 10:02 
GeneralRe: ASP.NET AJAX 1.0 Problem Pin
dhejov15-Aug-10 19:39
memberdhejov15-Aug-10 19:39 
GeneralVB.Net version using ICSharpCode.SharpZipLib Pin
aka200527-Nov-06 8:26
memberaka200527-Nov-06 8:26 
Questiondose it make server busy? Pin
huobazi@aspxboy.com25-Nov-06 6:02
memberhuobazi@aspxboy.com25-Nov-06 6:02 
AnswerRe: dose it make server busy? Pin
adriancs3-Jun-14 20:14
professionaladriancs3-Jun-14 20:14 
GeneralExcellent. Pin
deepaks328-Aug-06 21:13
memberdeepaks328-Aug-06 21:13 
GeneralServer Side Pin
jonavi18-Jul-06 2:08
memberjonavi18-Jul-06 2:08 
GeneralRe: Server Side Pin
Dario Solera18-Jul-06 2:24
memberDario Solera18-Jul-06 2:24 
GeneralRe: Server Side Pin
jonavi18-Jul-06 2:29
memberjonavi18-Jul-06 2:29 
GeneralRe: Server Side Pin
Dario Solera18-Jul-06 2:36
memberDario Solera18-Jul-06 2:36 
GeneralRe: Server Side Pin
jonavi18-Jul-06 2:38
memberjonavi18-Jul-06 2:38 
GeneralRe: Server Side Pin
Dario Solera18-Jul-06 2:47
memberDario Solera18-Jul-06 2:47 
GeneralRe: Server Side Pin
jonavi18-Jul-06 3:38
memberjonavi18-Jul-06 3:38 
GeneralRe: Server Side Pin
Dario Solera18-Jul-06 21:46
memberDario Solera18-Jul-06 21:46 
GeneralRe: Server Side Pin
jonavi18-Jul-06 3:16
memberjonavi18-Jul-06 3:16 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160525.2 | Last Updated 10 Jul 2006
Article Copyright 2006 by Dario Solera
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid