Failed to load viewstate .. + dynamically loading User Controls
After implementing Page Controller pattern and after we dynamically loaded user controls in child page we got the above exception. The exception was raised when we clicked on IE back button and then presses submit on the content user control entry form. The content user control entry form was loaded dynamically to the content placeHolder in the child page.
[For more details on this pattern check these links:
Page Controller
Implementing Page Controller in ASP.NET
The cause
The exception occurs because the viewstate of the page must be restored to its previous state. This mean we need to re-load any control we loaded dynamically before the page load had being triggered.
Solution:
step1: In base page page_load event u set a session variable with the content user control name
Session[Consts.SESSION_MENU_CONTENT] = PageContent;
base page always occured before child page load
step2: In child page DoPageLoad (which being called from base) u do the following
if (!Page.IsPostBack &&
Session[Consts.SESSION_MENU_CONTENT] != null &&
Session[Consts.SESSION_MENU_CONTENT].ToString() != string.Empty)
{
if (LoadedControlName != Session[Consts.SESSION_MENU_CONTENT].ToString())
{
contentHolder.Visible = true;
holderTitles.Visible = false;
contentHolder.Visible = true;
Session[Consts.SESSION_CURR_TAB_MENU_TITLE] = string.Empty;
contentHolder.Controls.Clear();
UserControl content = (UserControl)Page.LoadControl(Request.ApplicationPath + "/WebControls/" + Session[Consts.SESSION_MENU_CONTENT].ToString());
content.ID = "ctrlContent1";
contentHolder.Controls.Add(content);
}
}
step3: in the child page, OnInit event - before onload event on base page being called u should do the following
contentHolder.Visible=false;
holderTitles.Visible=true;
if (Page.IsPostBack)
{
if (Session["CurrentPageContent"] != null &&
Session["CurrentPageContent"].ToString() != string.Empty)
{
contentHolder.Visible = true;
holderTitles.Visible = false;
LoadedControlName = Session[Consts.SESSION_MENU_CONTENT].ToString();
contentHolder.Controls.Clear();
UserControl content = (UserControl)Page.LoadControl(Request.ApplicationPath + "/WebControls/" + Session["CurrentPageContent"].ToString());
content.ID = "ctrlContent1";
contentHolder.Controls.Add(content);
}
}
**LoadedControlName is a local field member that being set in OnInit when postback occured and we r re-load the existing current content user control which we keep its name in the Session