Dan Davies Brackett
Dan Davies Brackett

Reputation: 10071

ASP.Net: Why aren't the changes I make to Viewstate in a control event available to subsequent postbacks?

I'm writing a custom control in ASP.Net 3.5 WebForms, using ASP.Net AJAX. I'm building a state toggle into the control (expanded and collapsed modes). I've been trying to keep the current state of the control in ViewState, changing it in a server-side event handler manually:

object oExpanded = ViewState[ "Expandedness" ];
if(oExpanded == null)
{
    oExpanded = ListState.Collapsed;
}
ListState lsCurrentState = (ListState) oExpanded;
if(lsCurrentState == ListState.Collapsed)
{
    //code snipped - move to expanded mode here
    ViewState[ "Expandedness" ] = ListState.Expanded;
}
else
{
    //code snipped - move to collapsed mode here
    ViewState[ "Expandedness" ] = ListState.Collapsed;
}

I don't think it should matter, but the actual rendering happens in an updatepanel and the code above is in an event handler that's triggered asynchronously. The problem I have is that on the next postback, ViewState["Expandedness"] returns null. I've tried to use Fritz Onion's Viewstate Decoder tool to look at the actual contents of viewstate between postbacks, but it tells me the serialized data is invalid.

Have I taken a wrong approach here? What's the right way to tackle this problem?

Upvotes: 1

Views: 957

Answers (3)

teedyay
teedyay

Reputation: 23521

You're right that it's OK for it to be in an UpdatePanel - this shouldn't make any difference.

I suspect that the ViewState is disabled either for your control or for one of its parents: if it's disabled for any parent (all the way up to the page), it'll be disabled for your control.

To get round this, you can use the page's ViewState dictionary instead of the one on your control.

I.e. instead of saying:

this.ViewState[ "Expandedness" ] = ListState.Expanded;

say:

this.Page.ViewState[ "Expandedness" ] = ListState.Expanded;

If it's possible that there's more than one instance of your control on the page, you'll need to ensure the ViewState key is unique, perhaps like this:

this.Page.ViewState[ this.ClientID + "Expandedness" ] = ListState.Expanded;

As an alternative (that will work even if ViewState's disabled for the page), you could consider storing the Expandedness in the ControlState. It's a bit trickier, but google it and you'll find a code sample pretty quickly. It's recommended you store only an absolute minimum of information in the ControlState, but a single flag like this is fine (and actually what it's designed for, really).

Upvotes: 1

Dan Davies Brackett
Dan Davies Brackett

Reputation: 10071

Further investigation: The changes to Viewstate that I make in the sub-control event handler do last as long as Page_Prerender (i.e. later in the event lifecycle of the page), so the problem isn't that Viewstate isn't getting written to. But any subsequent postbacks to the page - synchronous or asynchronous - don't show that value in viewstate.

Upvotes: 0

AndreasKnudsen
AndreasKnudsen

Reputation: 3481

when do you call this code? if it is called in Page_Init it is too early, and any changes you do to the viewstate will be ignored.

Just a thought

Upvotes: 0

Related Questions