It has come to my attention that many visitors here have found me via a google search related to ViewState or something similar. For example, here's a google ranking one could be proud of! Unfortunately, not all the search results link directly to the article they seek, and it is buried 6 posts back so they don't always find it. If you're interested in my article on understanding the viewstate process, this post is for you. It's received a lot of interesting comments lately, so I think it deserves a little /bump anyway :)
Bringing ViewState into the Light
Download the source
YAVA (Yet another ViewState Article). For years now ViewState has remained hidden in the turbulent html source of our documents and applications. ASP.NET puts it there because, well, it isn't pretty. It's pretty ugly really.
Many ViewState Viewers are available that let you put on Base64 encoded glasses and see what's really in there. But sometimes I just want to have a good idea of what the size of my ViewState is on the various pages of my applications. If its too big, then I'll start thinking about optimizing it, which is when a decoder may come in handy. But to just get a feel for what its size is throughout my application, all I need is to look at the encoded string. But doing a "view source" every time is a pain.
ASP.NET 2.0 makes it easy to customize how ViewState is persisted. It even comes with two persisters of its own: HiddenFieldPageStatePersister and SessionPageStatePersister. Why not have a VisibleFieldPageStatePersister?
The cool thing about this simple persister is that it isn't just showing you what the ViewState is. The textarea is the field that the ViewState actually lives in. That means it's easy to change the ViewState for the page. Imagine you have a complex page with dozens of input fields on them, and you are trying to test a step in a process that is several steps behind those fields. It would be a pain to have to enter all those fields every time you wanted to debug. With this, you could copy the ViewState of the form at the point you'd like to return back to, and then assuming there were no server-side actions that you depend on having actually occurred, and ViewState is enabled on all the controls you need it for, you will instantly be back in that state.
WARNING: Do not let this make you think that ViewState is responsible for maintaining the state of posted input fields like TextBoxes and CheckBoxes. It isn't. Well it is, too. ViewState lets TextBoxes and such remember their state even when their value isn't naturally posted (such as when it's invisible, or people like us cheat the system as in this example). But normally TextBoxes and such remember their state simply because they are input forms, and even without ViewState their value is posted to the server. ViewState just makes it that much smarter at it (and enables things like TextChanged and CheckChanged events). So... if you have ViewState disabled on a TextBox, for example, this little trick won't restore it's state.
Here's an example. On this page, the "Click here!" button changes the label of the page, like so:
If we copy the text from the "previous" field into the "current" field, a postback occurs automagically, and the form returns to it's previous state.
How useful this really is, I'm not sure. There's plenty of room for improvement. For example, it could be extended to track the viewstate on every postback, allowing you to "go back" and "go forward", swapping the state along the way as appropriate. It could also have a built-in ViewState visualizer, that'd be handy. I haven't tested it in all scenarios... like when ViewState encryption is enabled. It definitely won't work if you limit the size of the ViewState field. Also, since it's using an actual TextBox control that it adds to the forms control collection, it's possible that code elsewhere on your pages could accidentally manipulate or otherwise disable the control.
The simplest way to use it is to make your page inherit from the included VisibleViewStatePage class (instead of just Page).
Download the source (C#) here
Happy coding! :)