How To: Compress ViewState in ASP.NET 2.0 with System.IO.Compression

ViewState is the built-in structure for automatically retaining values between multiple requests for the same page in ASP.NET. In other words, ViewState technology saves/restores page state between postbacks. On the other hand, this technology comes with an overhead that affects performance especially during page load since the state data is maintained in a hidden field.

Reducing ViewState Size

We can completely disable ViewState by setting EnableViewState to false in the page directive but you need extra programming effort for you to take care of the page state. It is a good idea to disable ViewState for the controls that do not actually need it such as Literals and Labels by setting EnableViewState to false. But this does not entirely solve the problem.

Compressing ViewState

ASP.NET 2.0 comes with the System.IO.Compression namespace, which contains classes with the functionality to compress/decompress streams. In ASP.NET 1.1, developers must use third-party compression tools such as ICSharpCode.SharpZipLib to compress ViewState.

Compressing/Decompressing using GZipStream

The following class contains two methods for compressing and decompressing a stream.

using System;
using System.Data;
using System.Configuration;
using System.IO;
using System.IO.Compression;

public static class CompressViewState
{
public static byte[] Compress(byte[] data)
{
    MemoryStream output = new MemoryStream();
    GZipStream gzip = new GZipStream(output,
                      CompressionMode.Compress, true);
    gzip.Write(data, 0, data.Length);
    gzip.Close();
    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);
    }
    gzip.Close();
    return output.ToArray();
}
}

You need to save this class in a .cs file in the App_Code directory.

Utilizing the CompressViewState Class

In order to compress the ViewState of a web page, you have to override the two methods LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium.

The following code creates a BasePage class that inherits from System. Web. UI. Page and web pages using the following Base Page class as the base class utilizes ViewState compression. The BasePage class adds an additional hidden field __COMPRESSEDVIEWSTATE, to store the compressed ViewState.

using System;
using System.IO;
using System.IO.Compression;
using System.Collections;
using System.ComponentModel;
using System.Web.UI;
using System.Configuration;
using System.Threading;
using System.Globalization;
using System.Text;

public abstract class BasePage : System.Web.UI.Page
{
 private ObjectStateFormatter _formatter =
     new ObjectStateFormatter();

 protected override void
     SavePageStateToPersistenceMedium(object viewState)
 {
     MemoryStream ms = new MemoryStream();
     _formatter.Serialize(ms, viewState);
     byte[] viewStateArray = ms.ToArray();
     ClientScript.RegisterHiddenField("__COMPRESSEDVIEWSTATE",
         Convert.ToBase64String(
         CompressViewState.Compress(viewStateArray)));
 }
 protected override object
     LoadPageStateFromPersistenceMedium()
 {
     string vsString = Request.Form["__COMPRESSEDVIEWSTATE"];
     byte[] bytes = Convert.FromBase64String(vsString);
     bytes = CompressViewState.Decompress(bytes);
     return _formatter.Deserialize(
         Convert.ToBase64String(bytes));
 }
} 

Check out the complete code

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CompressViewState.aspx.cs"
  Inherits="CompressViewState" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>
  <form id="form1" runat="server">
      <div>
          <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True">
          </asp:GridView>
      </div>
  </form>
</body>
</html>
using System;
using System.Data;
using System.Configuration;
using System.Collections;
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.Collections.Generic;
using System.Text;

public partial class CompressViewState : BasePage
{
   protected void Page_Load(object sender, EventArgs e)
   {
       if (!IsPostBack)
       {
           GridView1.DataSource = RandomStrings(1000);
           GridView1.DataBind();
       }

   }

   public static List<string> RandomStrings(int count)
   {
       List<string> strings = new List<string>();
       for (int i = 0; i < count; i++)
       {
           StringBuilder str = new StringBuilder();
           for (int j = 0; j < 10; j++)
           {
               str.Append(GetRandomLowerCaseCharacter(j));
           }
           strings.Add(str.ToString());
       }
       return strings;
   }
   public static char GetRandomLowerCaseCharacter(int j)
   {
       return ((char)((short)'a' + new Random((int)DateTime.Now.Ticks + j).Next(26)));
   }
}

Post a Comment

Please do not post any spam link in the comment box😊

Previous Post Next Post

Blog ads

CodeGuru