Skip navigation.

Lecturing, Giving TalksAll recent postsDon't Write Frameworks for Dummies

Overview of Page State Persisters

Today’s installment of nagging you to pay attention where your view state goes is about another ASP.NET 2.0 novelty: the PageStatePersister class.

The Old Suspects

In 1.x, if you wanted to move view state out of your pages and store it, say, in a database, you had to deal with the undocumented LosFromatter class (see my earlier view state article). It was a fudge, but it worked. We’ve used this approach for a couple of years.

New Faces

In 2.0, we have a fully documented PageStatePersister class. “Out of the box,” you use HiddenFieldPageStatePersister to keep view state in a hidden input element, __VIEWSTATE, like in them old days.

Another handy stock persister is SessionPageStatePersister which—you guessed it—persists view state in the session. This persister maintains a Queue of view state entries, 9 being the default (see <sessionPageState>).

The best part is that you can write your own persister. You can either override the Page.PageStatePersister property, or create a very simple adapter and list it in a .browser file for all pages. I prefer the latter option.

No Silver Bullet

I have not yet seen a fully functional sample of a database view state persister.

Simply storing a view state string in a file/session/database doesn’t work. As you go from page A to B and then click the browser Back button, you end up on page A, but you’ll load page B view state because the browser didn’t postback. Needless to say, your code will blow up.

The stock session persister takes it a step further by storing individual view state strings in, well, the session and tracks some other information. This approach doesn’t work either, because it causes trouble when you run frames in pages or pop up dialog windows—they use the same session, therefore they attempt to read view state stored by other pages within the same session.

I think the only viable way is to tie persistence logic to the session id and file name. Ultimately, if you go down the path of using a database for persistence, you need to keep track of the following bits:

  • session ID
  • timestamp (adjust with every save)
  • page file name

By trial and error we’ve figured out that these three guarantee enough uniqueness and will work with pop-ups, frames, and the like.

On the flip side, you have to deal with Session whims such as expiration, app restarts, etc. See my Session Q&A post where I outlined some issues that give me headaches.

You also need a mechanism to clean up view state entries of expired and abandoned sessions. This can be a SQL job or an HttpModule sitting on a timer.

Comments

Comment permalink 1 Dean Harding |
Another alternative would be to still include a __VIEWSTATE hidden field, but that it only contains a unique "ID" for the viewstate, which is stored somewhere on the server, rather than the actual viewstate itself.

Of course, this depends on why you're removing view state in the first place. If it's only because the __VIEWSTATE variable is getting "big" then this might be a better way to go about it.
Comment permalink 2 Milan Negovan |
As much as I'm obsessed with trimming view state, sometimes it gets large because some controls (*cough* DataGrid *cough*) can't page or sort without it.
Comment permalink 3 Per Zimmerman |
"Simply storing a view state string in a file/session/database doesn’t work. As you go from page A to B and then click the browser Back button, you end up on page A, but you’ll load page B view state because the browser didn’t postback. Needless to say, your code will blow up."

When you click back the page isn't reloaded. The ViewState won't be reloaded until you do a postback again.

"* session ID
* timestamp (adjust with every save)
* page file name

By trial and error we’ve figured out that these three guarantee enough uniqueness and will work with pop-ups, frames, and the like."

I don't think that's enough. If the user opens multiple windows showing the same page, the same viewstate would be used for those windows. The file name would be the same, but you would share viewstate between the windows.
Comment permalink 4 Milan Negovan |
Good point! I guess we never encountered this extreme case, but I can definitely see it happen.
Comment permalink 5 Abishek Bellamkonda |
I think, we need to store the Unique ID (i used Guid 2 years ago to do the same task) and ViewState String in database string. Which worked a treat, and we used this class in many sites too. This works for senarios where you go back an forth, do refresh.

Emails and Notifications

Would you like to be notified when somebody responds to this post?  Would you like to have these comments emailed to you?

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):