"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --Martin Fowler
We often get questions about ASP.NET Session and ViewState. Some time ago I put together an FAQ about Session and it seems to be popular. So now, a short one on ViewState.
What ViewState Isn't:
ViewState does not restore posted values to controls on a WebForm.
If you disable a control's ViewState, you will see that its value is still restored.
ViewState does not automatically recreate any controls that were dynamically created in the code.
Dynamically created controls on a page must be recreated when the page PostBack is processed.
ViewState is not for user or session data or for transferring data across pages.
Viewstate only can store data that is sent back to the same page during a PostBack operation.
ViewState does not hold "Controls".
Viewstate does not normally hold entire controls - only values and properties.
What ViewState is:
Viewstate represents the state of the page when it was last processed on the server. ViewState is used to track and restore the state values of controls that would otherwise be lost, either because those values do not post with the form or because they are not in the page html. A control defined solely in your page html with no changes made in the code will have no ViewState. ViewState only holds the values of properties that are dynamically changed somehow, usually in code, data-binding, or user interactions, so that they can be restored on each request. ViewSate does not hold "controls", it only hold values and the ID's of the controls they belong to.
ViewState also provides a StateBag, which is a special collection or dictionary, for each page. You can use this to store any object or value, associated with a key, to retain across PostBacks in a manner similar to the way you would store an object in Session state. This is useful for custom items that are relevant to only that specific page instance, since these values will automatically post with that page, but will not transfer to any other pages. One custom use of ViewState is to keep track of any dynamically created controls, which you can then manually recreate on each post based on your tracking data in ViewState. You do NOT store the Control in ViewState - you store the selected or entered value.
ViewState is serialized via the LOSFormatter class, which is a lightweight version of the BinaryFormatter, automatically serialized to or from a Base64 encoded string, and passed across page PostBacks as a hidden form field, __VIEWSTATE. For more info on how LOSFormatter works, see this article.
ViewState is saved before rendering in the Page.SavePageStateToPersistenceMedium method and it is restored on PostBacks in the Page.LoadPageStateFromPersistenceMedium method. Both of these methods can be overridden to save ViewState to Session, Cache, a Database, or even the file system.
Each control's ViewState is stored in a Triplet (System.Web.UI.Triplet) with the first object being a Pair (System.Web.UI.Pair) (or an Array of Pairs) of ArrayLists of related name-values. The second object of the Triplet is an ArrayList of that control's child indices in control tree, and the third object is an ArrayList of the similar associated Triplets of those child controls. Paul Wilson has an article that goes into much more detail. If you are interested in experimenting further, Fritz Onion has put together a nice GUI viewstate viewer here.
While developing a page, you can keep the size of the view state under control by enabling tracing on the page. Once you have set the @Page's trace attribute to true, look under the ViewState column of the control tree. This will give you a pretty good idea of what each control is doing. ViewState can be enabled or disabled on controls with the EnableViewState property.
More about ViewState:
Upon postback, the ASP.NET page framework parses the ViewState string and populates the ViewState properties for the page and each of the controls. The controls, in turn, use the ViewState data to rehydrate themselves to their former state.
There are five more useful things to know about ViewState.
- You must have a server-side form tag (<form runat=server>) in your ASPX page if you want to use ViewState. A form field is required so the hidden field that contains the ViewState information can post back to the server. It must be a server-side form so the ASP.NET page framework can add the hidden field when the page is executed on the server.
- The page itself saves 20 or so bytes of information into ViewState, which it uses to distribute PostBack data and ViewState values to the correct controls upon postback. So, even if ViewState is disabled for the page or application, you may see a few remaining bytes in ViewState.
In cases where the page does not post back, you can eliminate ViewState from a page by omitting the server side <form> tag.
In ASP.NET 2.0, there are additional ViewState enhancements, such as the
- To enable ViewState to work properly across machines in a web farm scenario, the MACHINEKEY element must be identical on each machine. Here is a short article that shows how to do this.
In many cases, developers want to avoid the use of ViewState. Rick Strahl has an excellent control he calls the PreserveProperty Control that offers many of the features of ViewState without the "baggage" in the page. I have "BackPorted" this control to ASP.NET 1.1 (VS.Net 2003 zip). ViewState can also be stored in Cache, Session, Global Static items, or even in a Database or on the FileSystem. Here is an article that explores the performance characteristics of some of these options, along with sample working code.