ViewState is a hugely useful feature of ASP.NET, but it's easy to misuse. It's also a little difficult to apprehend for ASP.NET beginners as it's working behind the scenes. The only thing you see at first is this huge blob on your page source.
If you don't know how ViewState works or what it's for, and even if you do, you should read this MSDN article. In a nutshell, ViewState is a state bag that's maintained from postback to postback. It materializes one of the scopes you can use to maintain state in your application:
- Context: local to the request (equivalent in scope to a page property).
- ViewState: local to the page, survives postbacks (but if you open two browsers on the same page, they have separate versions of the ViewState).
- Session: local to the remote user session (if you open two browsers using CTRL+N, they share the same session, but if you open two completely different instances of the browser, they don't), has a finite lifespan (20 minutes idle time by default), does not survive the browser closing. The Session can be shared across servers in a Web Farm.
- Cookies: local to the remote user account, can survive the browser closing, has a finite lifespan.
- Cache: local to the web application, shared by all users, not shared in a farm, expires based on a lifespan or arbitrary dependancies.
- Application: local to the Web application, shared by all users, not shared in a farm, doesn't expire except if the application is recycled.
- Static variables: shared by the whole application domain. Don't use that in a web application. Use Application variables instead (unles you really really know what you're doing).
The way it works is by tracking all changes from the moment TrackViewState is called, which happens normally between Init and Load. This means that any change you make after Init will be persisted to ViewState.
So the first thing you can do to reduce the viewstate is to do all initialization work during... yes, Init.
The data that you do want to persist across postbacks must be loaded during... you guessed it, Load.
The way it persists from postback to postback is by serializing all changes since tracking began into the __VIEWSTATE hidden HTML field. This is the big blob you see in your page. To avoid tampering, it is by default MAC-hashed.
There are a few reasons why you could want to completely disable ViewState (which is done by setting EnableViewState to false in the page directive or on any Control):
- Your page won't post back: pure contents pages, for example.
- Your page will post back, but the data will be completely different for every postback: a search results page where you handle the pagination logic using lazy loading, for example.
- Your page will post back, but you chose to rebind the data on every postback.
- The control does not handle postback data.
- The control does not persist any data.
- The control rebinds the data on every postback.
The third and sixth ones are particularly interesting because it's a decision you have to make in the context of your particular application. If the bandwidth the ViewState is eating costs you more than querying the database, then disable ViewState. Otherwise, keep it on but don't bloat it unnecessarily (by moving initialization code to Init and keeping persisted data loading in Load).
If you choose to requery the data on every postback, consider doing it in Init. This way, you can keep the data out of ViewState and still use the ViewState for other properties: you get finer granularity.
Another problem you may hit on ASP.NET 1.1 is that some controls do not like to have their ViewState disabled. DataGrid is one example of a control that more or less ceases to function properly without ViewState. That's why we introduced the concept of ControlState in ASP.NET 2.0. The ControlState is a part of ViewState that can't be disabled. It is used for these very few properties on each control that are absolutely necessary for the control to function. It could be the page number for a pagination control, for example. So in ASP.NET 2.0, you can safely disable ViewState on any of the new controls without them breaking down. GridView, which replaces DataGrid, is one of these controls.