guyS's WebLog

IShare, My DotNet Fingerprint

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

 

Comments

No Comments