There’s several useful custom page state persisters out there, which can help to get around the problem of huge viewstates.  These can do useful things like compress your viewstate or save it to disk and use a pointer.

One thing which is common in these implementations, is that they register a hidden field on the page to store the custom viewstate.  This is done using:

Page.ClientScript.RegisterHiddenField("__CUSTOMVIEWSTATEFIELD", viewState);

However, if you’re using this method, you will get some very unpredictable behaviour ajax behaviour with the standard asp.net ajax controls, like the UpdatePanel (the Telerik Ajax components all work perfectly).

The reason for this, is that the ViewState doesn’t get updated for ajax postbacks, as it’s now stored in a hidden field which isn’t updated when an ajax postback happens.

Suppose we have a linkbutton which toggles a panel’s visibility (on a page using a custom PageStatePersister with the above method of registering the hidden field).

protected void Toggle(object sender, EventArgs e)
{
 Panel1.Visible = !Panel1.Visible;
 Panel2.Visible = !Panel1.Visible;
}

 
 Panel1
 Panel2

When the page loads, Panel1 will be visible and Panel2 will be hidden. Clicking the ‘Toggle’ button will trigger an ajax postback toggling the two panels, making Panel1 hidden and Panel2 visible. However, clicking the button again will trigger an ajax postback but will not cause the panels visibility to toggle again.

The reason for this, is that the viewstate has become out of sync with the actual page, and therefore still thinks that Panel1 is visible and Panel2 is hidden.

Fortunately, the solution is simple. In your custom page state persister class, simply change the line above to:

ScriptManager.RegisterHiddenField(Page, "__CUSTOMVIEWSTATEFIELD", viewState);

This registers the new hidden field for storing viewstate with the ScriptManager, which then causes it to get updated with any ajax postbacks.