In the following lines, I’ll show how to create a very simple viewer that displays the content of the controls store in view state. It’s not just a tree holding all the ViewState data as stored in
__VIEWSTATE field, but a list of all the controls storing data in ViewState and the data saved in view state by each control. This will therefore work to reveal how ASP.NET arranges data regarding the controls saved in ViewState, and the data each one of those controls preserve.
As a part of the PostBack mechanism introduced in ASP.NET, Microsoft created the ViewState method to reduce page creation time at PostBack. The idea behind ViweState is simple: while page is created for the first time, some of the controls data are fetched from the data sources (such as the Database). When the user starts a server event from the client, all the page controls are recreated to process incoming server side events. To prevent access of data sources controls data, which wasn’t sent using HTML Form, it can be serialized into a hidden text field (
__VIEWSTATE) and sent to the client as a part of the HTML form. When a server side event is required, the hidden
__VIEWSTATE field that holds the control serialized data is sent over to the server. ASP.NET can use
__VIEWSTATE field preserved data to recreate controls instead of accessing data storage to get controls data. In addition to control usage of ViewState, ASP.NET enables programmers to add their own data into ViewState, so they can preserve the data over page calls.
You may ask then which controls use ViewState and what exactly they preserve in ViewState? I decided to take the challenge and to create a viewer displaying all the controls that preserve data in view state and the data that those controls preserve.
There are four main methods involved in handling ViewState in the
LoadPageStateFromPersistenceMedium methods are responsible for saving/loading ViewState to/from persistence medium (default persistence medium is a hidden field).
SaveViewState methods, actually handle the data which eventually loads/saves onto the persistence media. As part of ViewState handling
SaveViewStateRecursive methods of the
Control class are called from
SaveViewState methods to handle page controls ViewState recursively.
If you will override page
SavePageStateToPersistenceMedium method and inspect the only parameter that passes to
SavePageStateToPersistenceMedium, you will see that this parameter holds a tree of objects. Going down the tree you will see
Arrays. All of those container classes are used altogether to store
Page and controls ViewState. Triplets are classes consisting of three
Objects and Pairs, as the name would suggest, two. Every object of those classes can be another
Array and every one of them may contain other objects and so on.
Array may also contain strings and primitive types. ASP.NET uses
LosFormatter class to serialize ViewState tree into a text sent to the client in a hidden input (
A quick search in Google ends up with viewers that show only tree view of all
Array and primitive types. That's nice, but how can I identify the controls that stored the data and what exactly did they store in those endless
ArrayList tree. Specific information about which controls hold data inside ViewState and controls data must be somewhere inside ViewState. That is to say, since ASP.NET knows what ViewState data it needs to send for every control, I should start looking for that data in the ViewState tree.
How ASP.NET saves ViewState data
Apparently there is some logic behind that mass and it goes like this:
string) - Page hash value
ArrayList) - keys
ArrayList) – array that holds the control Position in Form controls collection.
ArrayList) - array that holds the ViewState for every control from the upper array.
Line 1: it all starts with a triplet (line 0). The first element of the first
Triplet holds a string that is a hash key of the control hierarchy of the page which stores ViewState data. The hash key value is passed through view state even if all
EnableViewstae properties are set to
Line 3: if that entry holds a
Pair, it means that the user asked to save data in the view state. If the user didn’t save any values to ViewState, this object sets to
Line 4: if Line 3 holds
Pair, this line is the first
Pair object which is
ArrayList of all the user Viewstate keys.
Line 5: if Line 3 holds
Pair, this line is the second
Pair object which is
ArrayList of all the user Viewstate values.
Line 6-7: The third object of the second
Triplet holds data about which control preserves data in ViewState and the data it preserves. The third object is actually an
Triplet objects that holds controls and data. Every entry in the third triplet object (
ArrayList) is another
Triplet object. That inner triplet holds the interesting data in the second and third objects.
Line 8: The second object in the above inner
Triplet is an
Arraylist. Every entry in that array holds a value that is the position of control in the controls collection of the
HtmlForm object (the
Line 9: Points to the third element of the inner
Triplet, that is an
Arraylist as well. Every entry in that array corresponds to the controls position array and actually holds data that is preserved by the control. That entry in array can be a single value or another complicated sub tree of
That’s for the logic of representing a control that preserves data and its data in the ViewState tree. Before we take a look at how to use this logic to display a page ViewState by controls, there are also other conclusions that I gathered regarding controls data structure. Those rules aren’t as firm as the controls logic. What I mean is that controls data rules are usually created but you can’t anticipate a scenario that control vendors might take to preserve data in ViewState.
Pairs’ two objects hold
ArrayList they usually represent key / value relationship between the
ArrayLists, where usually the first array holds the keys and the second array holds the values.
Triplets’ first object is primitive value while the second and third array holds
ArrayList then the
Triplet also holds
ArrayLists with Key / Value relationship. Usually the first object (primitive value) holds counter of the elements in the
ListArrays. As describe above, second and third
ArrayLists hold Key / Value data.
- There are scenarios where a
ArrayList in the second and third objects and the first object is set to
null. Those arrays hold Key / Value Data.
Triplet's first object is primitive type it usually holds data about the number of elements in the second and third objects.
Creating ViewState Viewer
I have implemented my simple viewer inside a separate class (
ViewStateViewer) so you could activate it from every page. All you need is simply to call the
ViewStateViewer's single public method (
GetPageControlsViewState will render tree with page, user defined and controls viewstate. Eventually it will look like the image at the top of the article.
The viewer class contains several private methods that are responsible for parsing the tree object recursively and displaying the data as tree; indeed they are pretty easy to follow. The interesting part goes into
GetPageControlsViewState method, which holds the logic of getting out from the ViewState data preserved by page, user and controls.
public void GetPageControlsViewState()
Create a new
HtmlGenericControl for holding the tree data that will be rendering on the page.
System.Web.UI.HtmlControls.HtmlGenericControl VSHtml = new
Check if current request holds PostBack data by checking the hidden field
__VIEWSTATE in request
Form collection. I use
HttpContext.Current.Handler for getting
Page object to make this code unbound to any
if(((Page)HttpContext.Current.Handler).Request.Form["__VIEWSTATE"] != null)
Get the string that holds the serialized data of ViewState and de-serialize it into an object.
string vsInput = ((Page)HttpContext.Current.Handler).Request.Form
["__VIEWSTATE"].Replace("\n", "").Replace("\r", "");
object vsObject = new LosFormatter().Deserialize(vsInput);
Getting the page ViewState is pretty easy. It’s always in the first element of the first
VSHtml.InnerHtml = "<b>Page Data : </b><br>" +
Check if the user added custom ViewState values by testing if the second object is a
Pair object type. If so, then get the keys and values arrays from the
Pair object and loop throughout those arrays to get the key / value pairs and display them.
Triplet Second = (Triplet)((Triplet)vsObject).Second;
if (Second.First is System.Web.UI.Pair)
System.Web.UI.Pair oPair = (System.Web.UI.Pair)Second.First;
System.Collections.ArrayList oKeys =
System.Collections.ArrayList oVals =
VSHtml.InnerHtml += "<br><b> User ViewState : </b><BR>";
for(int i = 0; i<oKeys.Count; i++)
VSHtml.InnerHtml += "\t Key=" + oKeys[i].ToString () +
" Value=" + oVals[i].ToString () + "<br>";
Get the third object and loop through the
ArrayList oArrObjectsAndData = (ArrayList)Second.Third;
for (int iObjAndData=0;iObjAndData<oArrObjectsAndData.Count;iObjAndData++)
Triplet object from
ArrayList and then cast the second (holding objects representation) and the third (ViewState data) objects to
Triplet oTripControls = (Triplet)oArrObjectsAndData[iObjAndData];
ArrayList oArrObjects = (ArrayList)oTripControls.Second;
ArrayList oArrData = (ArrayList)oTripControls.Third;
Loop through the objects
ArrayList. For each object:
- Get its ID from
HtmlForm controls by using control position in the
- Get ViewState data of the control from the
ArrayList and parse it.
for(int iCont =0; iCont < oArrObjects.Count; iCont++)
string ContID = GetForm().Controls[(int)oArrObjects[iCont]].ID;
Triplet oTrip = (Triplet)oArrData[iCont];
VSHtml.InnerHtml += "<br><b>" + ContID + " : </b><BR>" +
HtmlGenericControl visibility and add it to the parse form collection.
VSHtml.Visible = true;
If you look in the results, you can see that every control has its logic for storing ViewState.
Triplet with two arrays. One holds the display values and the other holds their corresponding values. Grid saves several arrays that hold general information about itself (number of rows, page etc.) and values and value types for each cell. With a small effort, you can create custom viewer for each server control, check for the type of the control that preserves data and use its custom viewer.
Using this code, you can easily see which objects preserve data in the ViewState and what data the objects are preserving. If you take it one step ahead, you can develop custom viewers to display server control view state in a more readable manner.