views:

299

answers:

1

I'm having a problem in my ASP.NET application with Viewstate and F5 page refresh.

If after navigating from one page to another I immediately hit F5, I get the following error:

System.InvalidCastException 
"Unable to cast object of type 'System.Web.UI.Triplet' 
to type 'System.Web.UI.Pair'."

This leads to the following exception displayed on the page:

HttpException (0x80004005): Failed to load viewstate.  The control tree 
into which viewstate is being loaded must match the control tree that 
was used to save viewstate during the previous request.  
For example, when adding controls dynamically, the controls added during a 
post-back must match the type and position of the controls added during 
the initial request.]
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +310
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +136
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +224
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +136
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +224
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +136
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +224
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +136
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +224
System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) +136
System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +224
System.Web.UI.Page.LoadAllState() +439
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1092

The point at which it fails is in the overriden LoadViewState method for a custom label control, when it calls the parent LoadViewState

System.Web.UI.WebControls.Label.LoadViewState(ByVal savedState As Object)

The savedState object appears to be for a completely different control (a drop down list) which is a System.Web.UI.Triplet, instead of the System.UI.Pair object expected by the Label control.

If I do the exactly the same thing using a different page in the same application, the page loads fine after the F5 postback. The two web pages inherit from the same base class and use the same custom controls. The page that is causing problems doesn't have any dynamically added controls.

Having debugged the process, it looks like the LoadViewState event is not being fired after the F5 postback for the controls on the page that loads successfully. SaveViewState is fired in both cases.

Any ideas why the LoadViewState event would be fired for one page but not the other? I'm fairly new to ASP.NET and I'm still getting my head around how ViewState works.

A: 

It's hard to say much without seeing your code. However, a few things that might help:

  1. You might want to look at the HTTP exchange during the failure using a web debugger like Fiddler; there's a good chance the answer will jump out at you.
  2. Remember that F5 re-issues the last request. If you're navigating from one page to another, there shouldn't be any ViewState at all, unless you're doing a cross-page post.
  3. If ViewState isn't being sent with the request, then perhaps the nature of the failure has something to do with the way you're encoding it?
  4. LoadViewState() should only be called when the incoming request contains ViewState that needs to be loaded into the associated control.
  5. SaveViewState() is called for every page request, to persist the control's state in a hidden field on the page, so that it's available during a postback.
RickNZ