Failed to load viewstate

J

Jed

I am getting the old "Failed to load viewstate." error and I can't figure out
why.

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. 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."

I am making a UserControl. It has two panels. Each panel represents an
alternate display mode. Both panels are wrapped in a primary panel.

The UserControl has a public DisplayMode property which determines which
panel to show. The point is that the mode will remain the same throughout
the "is or isn't postback" process. They are both declaratively set
Visible=False by default.

In the Init of the UserControl I hydrate the controls of the appropriate
panel and set it to visible. In other words this happens on postback too.

If I set the second panel on the UserControl to Visible the postback works,
however if I set the first panel to visible I get the ViewState error. I
have tried physically reversing them in design mode and the above holds true.

My controls are initialized before SaveViewState occurs. They are certainly
recreated by the same code on postback, so this error should not be occurring.

Obviously, if I set ViewState off it all works fine. I want ViewState on.
Why doesn't this work?
 
S

Steven Cheng[MSFT]

Hi Jed,

Welcome to the ASP.NET newsgroup.

From your description, you're developing an ASP.NET Usercontrol(ascx?)
which contains two panel which is used to hold the different sub controls
according to hte usercontrol's state/mode. And those controls in the two
panels are dynamically created and added into Panels. However, at runtime
you found that when set the current state to a certain value(one of the
panel) visible, the postback will result to a "load viewstate . .." error,
correct? If anything I missed , please let me know.

As for ASP.NET webcontrol, if we're dynamically adding controls, we may
need to ensure the controls structure/collection remain the same between
postback so that those event or viewstate state can be correctly mapped.
Since the error message indicate that there is something incorrect with the
viewstate load/restore, we may first focus on those dynamically created
controls, have you tried remove those dynamic created controls or make them
static to see whether the problem goes away? This can help confirm that we
should focus on the panel's dynamic sub control collection.

Also, if convenient, I suggest you try creating a simplified
usercontrol(still contains two panels, but simpflied the childcontrols
included in the panel) which can reproduce the same problem so that we can
take a further look and test on it.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jed

Hi Steven,

I went ahead and simplified the control. I removed one of the panels, and I
am still getting the error, which is "good" because I want to figure out what
is going on.

It is an ASP.NET UserControl(ascx). This is all there is to it.

<asp:panel id="SearchPanel" runat="server" cssclass="SearchPanel">
<div>
<span>Used/New:</span>
<span><asp:dropdownlist id="UsedNewDropDownList"
runat="server"></asp:dropdownlist></span>
<span>Type:</span>
<span><asp:dropdownlist id="TypeDropDownList"
runat="server"></asp:dropdownlist></span>
<span>Manufacturer:</span>
<span><asp:dropdownlist id="ManufacturerDropDownList"
runat="server"></asp:dropdownlist></span>
<span><asp:button id="SearchButton" runat="server" text="Search"
/></span>
</div>
</asp:panel>

In the OnInit, I call the database and bind the DropDownLists to the
appropriate instance of List<T>. I am not doing anything fancy. I would say
I am not even "creating" dynamic controls. Everything should be there
before the viewstate kicks in.

I handle the click event of the button and if appropriate send the user to
the results page with a Response.Redirect. However, the page never makes it
that far. I get the viewstate error immdiately after clicking the button.
 
S

Steven Cheng[MSFT]

Thanks for your response Jed,

I've just performed a simple test depend on the test ascx file you
provided. I used a SqlDataSource control to bind the three dropdownlists on
the ascx(in OnInit event). Seems it works well , there is not viewstate
error when I click the "search" button. I'm adding the usercontrol
statically on the host page. Here is my test usercontrol's complete
template and codebehind:

=========ascx==============
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TestUCl.ascx.cs"
Inherits="UserControls_TestUCl" %>
<asp:panel id="SearchPanel" runat="server" cssclass="SearchPanel">
<div>
<span>Used/New:</span>
<span><asp:dropdownlist id="UsedNewDropDownList"
runat="server"></asp:dropdownlist></span>
<span>Type:</span>
<span><asp:dropdownlist id="TypeDropDownList"
runat="server"></asp:dropdownlist></span>
<span>Manufacturer:</span>
<span><asp:dropdownlist id="ManufacturerDropDownList"
runat="server"></asp:dropdownlist></span>
<span><asp:button id="SearchButton" runat="server" text="Search"
OnClick="SearchButton_Click"
/></span>
</div>
</asp:panel>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$
ConnectionStrings:LocalSQL2000Northwind %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM
[Categories]"></asp:SqlDataSource>

===========code behind==========

public partial class UserControls_TestUCl : System.Web.UI.UserControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);


if(!IsPostBack)
{


this.UsedNewDropDownList.DataSource =
SqlDataSource1.Select(DataSourceSelectArguments.Empty);
this.UsedNewDropDownList.DataBind();

this.TypeDropDownList.DataSource =
SqlDataSource1.Select(DataSourceSelectArguments.Empty);
this.TypeDropDownList.DataBind();

this.ManufacturerDropDownList.DataSource =
SqlDataSource1.Select(DataSourceSelectArguments.Empty);
this.ManufacturerDropDownList.DataBind();
}


}
protected void Page_Load(object sender, EventArgs e)
{

}
protected void SearchButton_Click(object sender, EventArgs e)
{
Response.Write("<br/>SearchButton_Click " +
DateTime.Now.ToShortTimeString());
}
}
=========================

If convenient, you can also post the test custom class(which used to bind
the dropdownlist through generic List<>)

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jed

That's interesting. Here's what I have that doesn't work. If I enable
viewstate in the oninit then I have trouble.


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using MyCompany.Data;
using MyCompany;
using MyCompany.Utilities;
using MyCompany.Web.Context;

public partial class MyCompany_UserControls_Search :
MyCompany.Web.UI.BaseUserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}

private SP_GetSearchListsByBasic _dataSource;
public SP_GetSearchListsByBasic ControlDataSource
{
get
{
if (_dataSource == null)
{
_dataSource = SP_GetSearchListsByBasic.Execute(new
SP_GetSearchListsByBasic.Criteria(this.BasePage.DealerInfo.DealerId));
}
return _dataSource;
}
}

protected override void OnInit(EventArgs e)
{
base.EnableViewState = false;
base.OnInit(e);
InitializeControl();
this.SearchButton.Click += new EventHandler(SearchButton_Click);
}

protected override void OnApplyStyle(object sender, EventArgs e)
{
if (this.DefaultCss == string.Empty) { this.DefaultCss =
"Default.css"; };
base.OnApplyStyle(sender, e);
}

private void SearchButton_Click(object sender, EventArgs e)
{
string status = this.UsedNewDropDownList.SelectedValue;
string manufacturerId = this.ManufacturerDropDownList.SelectedValue;
string typeId = this.TypeDropDownList.SelectedValue;
DoSearch(status, Parse.ParseInt(manufacturerId),
Parse.ParseInt(typeId));
}

private void DoSearch(string status, int manufacturerId, int typeId)
{
string url = this.ResolveUrl(ConfigSettings.SearchResultsPage);
if (status.Length > 0)
{
url = this.BasePage.Website.ChangeQueryStringParameterValue(url,
QueryStringNames.Instance.Status, status);
}
if (manufacturerId > 0)
{
url = this.BasePage.Website.ChangeQueryStringParameterValue(url,
QueryStringNames.Instance.ManufacturerId, manufacturerId.ToString());
}
if (typeId > 0)
{
url = this.BasePage.Website.ChangeQueryStringParameterValue(url,
QueryStringNames.Instance.TypeId, typeId.ToString());
}
Response.Redirect(url);
}

private void InitializeControl()
{
InitializeSearchPanel();
}

private void InitializeSearchPanel()
{
FillNewUsed(this.UsedNewDropDownList);
FillManufacturers(this.ManufacturerDropDownList);
FillRvTypes(this.TypeDropDownList);
}

private void FillNewUsed(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.Items.Add(new ListItem("New and Used", "Any"));
listControl.Items.Add(new ListItem("New Only", "New"));
listControl.Items.Add(new ListItem("Used Only", "Used"));
}
if
(listControl.Items.FindByValue(this.BasePage.Website.QueryString.Status) !=
null)
{
listControl.SelectedValue =
this.BasePage.Website.QueryString.Status;
}

}

private void FillManufacturers(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.DataTextField = "Name";
listControl.DataValueField = "Id";
listControl.DataSource = this.ControlDataSource.Manufacturers;
listControl.DataBind();
listControl.Items.Insert(0, new ListItem("Choose Manufacturer",
"0"));
}
if
(listControl.Items.FindByValue(this.BasePage.Website.QueryString.ManufacturerId.ToString()) != null)
{
listControl.SelectedValue =
this.BasePage.Website.QueryString.ManufacturerId.ToString();
}

}

private void FillRvTypes(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.DataTextField = "Name";
listControl.DataValueField = "Id";
listControl.DataSource = this.ControlDataSource.RvTypes;
listControl.DataBind();
listControl.Items.Insert(0, new ListItem("Choose RV Type", "0"));
}
if
(listControl.Items.FindByValue(this.BasePage.Website.QueryString.TypeId.ToString()) != null)
{
listControl.SelectedValue =
this.BasePage.Website.QueryString.TypeId.ToString();
}

}
}
 
S

Steven Cheng[MSFT]

Hi Jed,

Thanks for the response.

I've performed some further test through your code behind (and the ascx
template in former message). Since I haven't the complete code and
reference library, I comment out some busness logic specific class code.
Here is my test usercontrol's code(ascx remain the same, only add a
sqldatasource control for testing). Also, I disabled the ViewState of the
usercontrol through @Control directive like:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CUUC.ascx.cs"
Inherits="UserControls_CUUC"
EnableViewState="false" %>

And seems the control still works well without any viewstate error on
postback.

=========modified codebehind=============
public partial class UserControls_CUUC : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}

//private SP_GetSearchListsByBasic _dataSource;

//private DataTable
// public SP_GetSearchListsByBasic ControlDataSource
// {
// get
// {
// if (_dataSource == null)
// {
// _dataSource = SP_GetSearchListsByBasic.Execute(new
//SP_GetSearchListsByBasic.Criteria(this.BasePage.DealerInfo.DealerId));
// }
// return _dataSource;
// }
// }


protected override void OnInit(EventArgs e)
{

base.OnInit(e);
InitializeControl();
this.SearchButton.Click += new EventHandler(SearchButton_Click);//
protected override void OnApplyStyle(object sender, EventArgs e)
// {
// if (this.DefaultCss == string.Empty)
// {
// this.DefaultCss =
//"Default.css";
// };
// base.OnApplyStyle(sender, e);
// }
}



private void SearchButton_Click(object sender, EventArgs e)
{
string status = this.UsedNewDropDownList.SelectedValue;
string manufacturerId = this.ManufacturerDropDownList.SelectedValue;
string typeId = this.TypeDropDownList.SelectedValue;
DoSearch(status, int.Parse(manufacturerId),
int.Parse(typeId));
}

private void DoSearch(string status, int manufacturerId, int typeId)
{
// string url = this.ResolveUrl(ConfigSettings.SearchResultsPage);
// if (status.Length > 0)
// {
// url =
this.BasePage.Website.ChangeQueryStringParameterValue(url,
//QueryStringNames.Instance.Status, status);
// }
// if (manufacturerId > 0)
// {
// url =
this.BasePage.Website.ChangeQueryStringParameterValue(url,
//QueryStringNames.Instance.ManufacturerId, manufacturerId.ToString());
// }
// if (typeId > 0)
// {
// url =
this.BasePage.Website.ChangeQueryStringParameterValue(url,
//QueryStringNames.Instance.TypeId, typeId.ToString());
// }
// Response.Redirect(url);
}

private void InitializeControl()
{
InitializeSearchPanel();
}

private void InitializeSearchPanel()
{
FillNewUsed(this.UsedNewDropDownList);
FillManufacturers(this.ManufacturerDropDownList);
FillRvTypes(this.TypeDropDownList);
}

private void FillNewUsed(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.Items.Add(new ListItem("New and Used", "Any"));
listControl.Items.Add(new ListItem("New Only", "New"));
listControl.Items.Add(new ListItem("Used Only", "Used"));
}
// if
//(listControl.Items.FindByValue(this.BasePage.Website.QueryString.Status)
!=
//null)
// {
// listControl.SelectedValue =
//this.BasePage.Website.QueryString.Status;
// }

}

private void FillManufacturers(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.DataTextField = "CategoryName";
listControl.DataValueField = "CategoryID";
listControl.DataSource = this.SqlDataSource1;
listControl.DataBind();
listControl.Items.Insert(0, new ListItem("Choose Manufacturer",
"0"));
}
// if
//(listControl.Items.FindByValue(this.BasePage.Website.QueryString.Manufactu
rerId.ToString()) != null)
// {
// listControl.SelectedValue =
//this.BasePage.Website.QueryString.ManufacturerId.ToString();
// }

}

private void FillRvTypes(ListControl listControl)
{
if (listControl.Items.Count == 0)
{
listControl.Items.Clear();
listControl.DataTextField = "CategoryName";
listControl.DataValueField = "CategoryID";
listControl.DataSource = this.SqlDataSource1;
listControl.DataBind();
listControl.Items.Insert(0, new ListItem("Choose RV Type",
"0"));
}


// if
//(listControl.Items.FindByValue(this.BasePage.Website.QueryString.TypeId.To
String()) != null)
// {
// listControl.SelectedValue =
//this.BasePage.Website.QueryString.TypeId.ToString();
// }

}

}
==========================

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jed

Hi, Steven,

I realize that if I disable the ViewState the control works. I guess I
don't understand what is new in 2.0 that requires this. In 1.1I could create
and modify the control tree in the Init without any problems with ViewState.
There really isn't much going on in my base class. It seems like a fairly
basic scenario, so there must be something quirky happening.

Well, thanks for the help. I really appreciate the time you have spent
trying to understand this issue. I guess I will keep fiddling with it until
I can make sense of things.
 
S

Steven Cheng[MSFT]

Thanks for your further followup.

Glad that my work is of assistance to you. As always, please feel free to
post here when there is anything we can help you.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jed

Hi Steven,

I thought I would followup with what I believe was the explanation for the
problem I was experiencing.

I am using the SessionPageStatePersister in a PageStateAdapter to persist
the ViewState in the Session. I am also using a BasePage. The UseControl I
wrote exists on "Page1". On postback I do a Request.Redirect to "Page2".
The only problem is both Page1 and Page2 inherit from the BasePage. Since
the ViewState is in the Session Page2 tries to load it, but unfortunately it
is Page1's ViewState and it doesn't match.

Normally of course this wouldn't be a problem because a redirect doesn't
send "__VIEWSTATE" param, but since it is in the Session, I think it is
getting messed up.

The answer for now is to clear the ViewState in the base.OnInit() if Request
isn't a PostBack:

if (!this.IsPostBack)
{
this.ViewState.Clear();
}

Does this make sense?

Thanks for all the help!
 
S

Steven Cheng[MSFT]

Thanks for your followup,

Yes, this make it much clearer. Really unexpect that you're using custom
sessionState module:)

Glad that you've figured it out.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

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,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top