Remove ViewState from an ASP.NET Page

In this post, we will explore how to remove ViewState from your asp.net page and instead store it in a session. This could be useful when pages are to be served to devices with less resources.

Since HTTP is a stateless protocol, the state of controls is not saved between postbacks. One of the ways to get around this is to use ViewState in ASP.NET. ViewState is the means of storing the state of server side controls in HTML hidden fields, between postbacks. For this example, on a button click, I have set the label text to ‘I Love DevCurry’. Here’s a sample viewstate shown below.

Viewstate hidden field

Although the viewstate looks decrypted, but it isn’t. It is a Base64 encoded string which can be decoded. You can easily use an online viewstate decoder to decode the string or read my post How to view information in ViewState using ASP.NET to create a simple decoder tool of your own.

Here’s the decoded viewstate

viewstate decode

As you can see, the string that was stored in the viewstate can be seen once we have decoded the viewstate. You have a couple of options to protect your ViewState.

1. Encrypt ViewState - You can encrypt a ViewState by using the viewStateEncryptionMode option in your web.config or in your page.

2. The second option is to use the ViewStateUserKey Property to prevent web attacks.

3. The third option and the focus of this article is to remove the ViewState from the page and instead store it in a session state.

By default, view state is stored on the client using the HiddenFieldPageStatePersister class. However this option can be overridden and instead ViewState can be saved in a Session state using the PageStatePersister class. Add the following code in the code-behind of your page

PageStatePersister

That’s it. Run the page > Right click > view source > copy the viewstate and run it in the viewstate decoder. Here’s what you get.

viewstate decode

As you can see, the viewstate no longer holds any values. That is because the viewstate is now stored in the session state.

Note: Use this approach carefully and selectively as you may run out of memory if you overuse it.

You may also want to read What's New in ASP.NET 4.0 – Better ViewState Control






About The Author

Suprotim Agarwal
Suprotim Agarwal, Developer Technologies MVP (Microsoft Most Valuable Professional) is the founder and contributor for DevCurry, DotNetCurry and SQLServerCurry. He is the Chief Editor of a Developer Magazine called DNC Magazine. He has also authored two Books - 51 Recipes using jQuery with ASP.NET Controls. and The Absolutely Awesome jQuery CookBook.

Follow him on twitter @suprotimagarwal.

3 comments:

Mark Hildreth said...

Just a tip - the code above is what is recommended in the MSDN documentation, but it has a bug. If you use GridView's or other controls that utilize Control State on your page, you may run into problems. The solution is to override the property like so:

private PageStatePersister _PageStatePersister;
protected override PageStatePersister PageStatePersister
{
get
{
if(_PageStatePersister == null)
{
_PageStatePersister = new SessionPageStatePersister(this.Page);
}
return _PageStatePersister;
}
}

That way, you can hang on to the same instance of the SessionPageStatePersister during the lifetime of the Page, which will help keep the control state operations consistent.

Suprotim Agarwal said...

That's a good tip Mike. ControlState in a Grid cannot be disabled (if i recall correctly) so that means your tip is applicable to everyone using the Gridview + who's storing viewstate in the Session. Is the bug documented officially and can you point me to a link.

On a side not to all readers, it is recommended to explicitly use ControlState "only for small amounts of critical data that are essential for the control across postbacks". It is not a replacement for viewstate.

Jonathan Wood said...

Hey, thanks. This topics seemed obscuure but was easy to follow.

I was sure my view state data was encrypted but apparently not.

As you say, you need to be careful with this approach as it'll use much more memory on the server. However, it is still useful to know how this can be overridden.