Failed to load viewstate

D

Dan

I'm trying to replace my panels with usercontrols. On
pageload, I pull an array and it's index from the session
and I load a corresponding usercontrol and add it to a
placeholder. This control dynamically gets webcontrols
added to it. When user clicks next, I remove the control,
get the next control in the array and add it to the
placeholder. This works good. When user clicks back, I
remove the current control, get the previous control and
load it. During the pageload of this control i try to
dynamically add webcontrols again and I get this error.

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.

I've also tried to set the existing control to invisible
instead of removing it, but I still get this error.

Help
 
T

Teemu Keiski

Dynamical controls should be added on every request and on same order.
ViewState saving and loading mechanism relies on control's index on control
tree (it does not use IDs whatsoever) so therefore you can get this error if
you modify the control tree improperly say put control A on index 2 on first
request and on index 5 on next one and so on.

Post some code which causes you the error and we can take a look at it.

--
Teemu Keiski
MCP, Designer/Developer
Mansoft tietotekniikka Oy
http://www.mansoft.fi

AspInsiders Member, www.aspinsiders.com
ASP.NET Forums Moderator, www.asp.net
AspAlliance Columnist, www.aspalliance.com
 
D

Dan Rush

Okay, Here is the web page page load method:

private void Page_Load(object sender, System.EventArgs e)
{
myReq = (SupportRequest)Session["request"];
if (myReq.options.Count > 0 && myReq.optionIndex <
myReq.options.Count)
{
opt = (Option)myReq.options[myReq.optionIndex];
opt.LoadPanel(this);
}
}

Here is Option's LoadPanel method:

public void LoadPanel(System.Web.UI.Page page)
{
// Load user control
userControl = (UserControl)page.LoadControl ("Controls\\UserControl" +
this.type + ".ascx");
PlaceHolder plh = (PlaceHolder)page.FindControl("plhControls");
plh.Controls.Add(userControl);
}

Here is Option's Next button action:

private void btnNext_Click(object sender, System.EventArgs e)
{
myReq = (SupportRequest)Session["request"];
Option opt = (Option)myReq.options[myReq.optionIndex];

// Save current page and turn it off
System.Web.UI.Page page = this.Page;
opt.SavePanel(page); // this removes the usercontrol from a
placeholder on the page using plh.Controls.RemoveAt(0)
opt.Save();

myReq.optionIndex++;

if (myReq.optionIndex < myReq.options.Count)
{
opt = (Option)myReq.options[myReq.optionIndex];
opt.LoadPanel(page);
}
}

Here is a Back button action:

private void btnSumBack_Click(object sender, System.EventArgs e)
{
SupportRequest myReq = (SupportRequest)Session["request"];
System.Web.UI.Page page = this.Page;

PlaceHolder plh = (PlaceHolder)page.FindControl("plhControls");
plh.Controls.RemoveAt(0);

myReq.optionIndex--;

if (myReq.options.Count > 0)
{
opt = (Option)myReq.options[myReq.optionIndex];
opt.LoadPanel(page);
}
}
 
T

Teemu Keiski

I know this sounds tedious, but if you replace control with others on
control tree (between requests) you get problems as control do not get
correct ViewState returned etc (as I said they use indexes to save/restore
viewstate).

Other thing is that you can't add control that does postback processing
(Button or TextBox) on event handler itself. Reason is that those controls
get the postback events raised right after Page_Load and if you add control
on postback event, it won't get it's events raised on the proper request (on
the first postback) but raises them on the second (like on postback behind
all the time), as you explained the behaviour.

I would suggest that you'd add all controls to the control tree and do not
conditionalize the adding, but manage their visibility property. That way
you'd get only desired controls visible/not visible, but wouldn't suffer any
problems with postbacks whatsoever.

--
Teemu Keiski
MCP, Designer/Developer
Mansoft tietotekniikka Oy
http://www.mansoft.fi

AspInsiders Member, www.aspinsiders.com
ASP.NET Forums Moderator, www.asp.net
AspAlliance Columnist, www.aspalliance.com
 
D

Dan Rush

concur about adding all controls and making one visible at at time to
simulate multiple pages.

So in my pageload method I do something like this?

Page_load()
{
If not postback,
{
Loop through array, load all controls
}

Controls[index].Visible = true;

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top