ViewState 101

One of the most common complaints I hear about the Infragistics tools is “there’s so much ViewState, it’s bloated!”.  One of the most common questions I hear is not surprisingly, “How do I reduce the ViewState?”.  Before I jump into the answer (which is a simple “turn it off”), I want to discuss what ViewState is.

ViewState is an encoded string that is actually a list of serialized properties and values for a given control.  Viewstate is how ASP.NET knows if a property has changed between postbacks.  Suppose I had a textbox and I wanted to change the background color to red when the user clicks on a button.  Easy task right?  Well, what happens if the user then clicks on a different button.  How does the application know to make the textbox red again?  The button click code isn’t going to fire again, and the Page no longer exists on the server (it’s torn down and re-created with each request/postback).  The fact that the background should now be read has to be stored somewhere – that somewhere is ViewState.  Here’s some code:

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

<%@ Register Assembly="Infragistics35.WebUI.WebDataInput.v8.3, Version=8.3.20083.1002, Culture=neutral, PublicKeyToken=7dd5c3163f2cd0cb"
    Namespace="Infragistics.WebUI.WebDataInput" TagPrefix="igtxt" %>

<!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></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <igtxt:WebNumericEdit ID="WebNumericEdit1" runat="server">
        </igtxt:WebNumericEdit>
        <asp:Button runat="server" Text="Red" OnClick="TurnRed" />
        <asp:Button runat="server" Text="Submit" />
    </div>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void TurnRed(object sender, EventArgs e)
    {
        this.WebNumericEdit1.BackColor = Color.Red;
    }
}

Clicking on the “Red” button turns the background of my textbox red.  Then if I click on the “Submit” button and force a postback, the textbox background remains red.  We often just take for granted that this works, but it’s ViewState that makes this work.  Look at the HTML source in your browser and you’ll see something like:

<input type=”hidden” name=”__VIEWSTATE” value=”…..” />  The ViewState is stored as a string value in a hidden field, and it keeps track of all changes made at runtime to a particular object.  When you set the backcolor to Red on the WebNumericEdit, that information gets encoded into the value seen in the __VIEWSTATE field.  The next time the page is posted back, the control peeks into the __VIEWSTATE field and re-serializes itself based on what it finds.  Let’s take a look at the example code above.  When the page initially loads, this is what the __VIEWSTATE field looks like:

<INPUT id=__VIEWSTATE value=/wEPDwUKLTIyOTMwMjU4MmQYAQUeX19Db250
cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFD1dlYk51bWVyaWNFZGl0MROii26o
a0DVPVO5sgHn/KcNr5fL type=hidden name=__VIEWSTATE>

That’s not very telling, so lets use a tool to decode this into clear text.  You can download ViewState Decoder which is what I’m using below.

image

Notice that there’s not really anything of note in the ViewState except for what looks like some sort of identifier key.  Now let's click on the Red Button and see what we get.

image

Notice there’s now an entry for a Color [Red].  If this value was not included in the __VIEWSTATE field, the next time the Page posted back, the background color would reset to White (the default).  To understand more about how this works, lets take a look at the control lifecyle.

image

The first phase after a Page is requested is the Init, where the objects are created from the ASPX markup.  After the Init the ViewState is “rehydrated” (deserialized) and the values are loaded into the appropriate controls/properties. 

Note: This is a simplified model.   There are additional steps like loading ControlState, and firing Events that I’ve left out for clarity. 

Notice that the last step before Render is “SaveViewState”.  When this method is called, every property that was ‘dirtied’ during the Page_Load will be persisted into the Value attribute of the __VIEWSTATE hidden field.  Yes, I said – EVERY property.  That’s the drawback of using ViewState, and the reason why it’s important to understand how it functions.

If you’re used to putting all of your initialization code in the Page_Load, inside of an if statement that checks that it’s not a PostBack, chances are you don’t need ViewState.  Removing the if statement and having that code execute on each Page_Load will allow you to set EnableViewState=False on a particular control, or even the entire Page.  The only case this doesn’t cover is the “I want to change the background-color of my TextBox to red on a Button Click”. 

So you’ve read this far, I’m guessing you want an answer to the questions at the top?

Q: “Why is the ViewState field so big for Infragistics controls!?”

A: The size of the ViewState field is directly dependent on the number of properties you’re setting – as per the definition of ViewState.  We’ve gone to great lengths to ensure that each property of our components participates in the ViewState lifecycle.  That means if you set 200 properties in your Page_Load, 200 properties will end up in ViewState, just as you should expect.

Q: “Do I need ViewState?”

A: The short answer is no.  In the scenarios above, I highlighted when and where you would want to use ViewState.  Infragistics controls are meant to work with or without ViewState.  If you don’t need to support the “I want to change the background-color of my TextBox to red on a Button Click” scenario, you can simply turn off ViewState.  The only time I use ViewState is when I forget to turn it off.

Q: “How do I reduce the ViewState?”

A: Turn it off.  There’s no in between for ViewState*, a control either tracks ViewState or it doesn’t.  Even though controls don’t need ViewState to function, it’s turned on by default for every control (as part of the .NET Framework).  Set EnableViewState=False on the control or Page level to turn off ViewState tracking.

 

*This brings me to one last topic, and one that takes the ViewState model to a whole new level – Grids.  The WebGrid has a commonly overlooked feature built into it where it can persist the entire datasource into ViewState.  Why do you need this you may ask?  When a grid is editable it needs to track the old value and the new value – that way it can fire the appropriate Update events and give you a chance to revert back to the ‘old’ value.  The old values can be persisted in ViewState in case your DataSource isn’t available the next time you post back.  There may be cases where you simply can’t fetch your DataSource on each postback (for performance reasons), or you manually populated the grid with data, and there is no “DataSource” to bind to.  In the WebGrid, you would turn off ViewState if you didn’t want the values to be persisted into the ViewState field.  Again, the default for all ASP.NET controls is to have ViewState enabled, so in your typical application you likely have this turned on (and you most likely don’t even need it). 

In the WebDataGrid we’ve made the ViewState serialization more granular and added a property to EnableDataViewState.  The property is self explanatory I think, but just to be clear – set this to True if you want to embed your data into ViewState, set it to False to keep data out of ViewState.  BTW, If you haven’t seen the WebDataGrid yet, go check it out now

So the next time someone says “The ViewState is too big”, not only can you save the day by showing them how to turn it off, but you can also explain how ViewState works and why it's there in the first place. 

2 Comments

  • @Richard - Great point, I almost forgot about that. However, in most cases the controls are placed on the design surface which in turn adds the control to the parent's control collection during the init phase of the page cycle.

  • even u turn off viewstate for textbox control, the retained value are displaying , kindly check.

Comments have been disabled for this content.