Viewstate Errors when loading dynamic user control

Hi all,

I've a really annoying problem with viewstate that I can't seem to figure out. I've an aspx page which dynamically loads web user controls into a panel. It loads about 10 user controls, 1 at a time. However, only 3 are causing issues.

FYI, I'm loading the user controls in the onint event as below:

protected override void OnInit(EventArgs e)
        {
            //If we're loading for the first time load default page.
            if (Session["wuc_location"] == null)
           {
               Session["wuc_location"] = "default_wuc.ascx";
               Session["wuc_ID"] = "WUC_default_wuc";
           }
           else
           {
               //Choose which WUC to load based on button clicked!
               switch ((string)Request.Form["__EVENTTARGET"])
               {
                   case "LinkButton_MM_Inbox":
                       Session["wuc_location"] = "administration_wuc.ascx";
                       Session["wuc_ID"] = "WUC_administration_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "LinkButton_MM_System_Logs":
                       Session["wuc_location"] = "logs_main_wuc.ascx";
                       Session["wuc_ID"] = "WUC_logs_main_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "LinkButton_MM_Preferences":
                       Session["wuc_location"] = "user_preferences_wuc.ascx";
                       Session["wuc_ID"] = "WUC_user_preferences_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "LinkButton_P20T":
                       Session["wuc_location"] = "previous_20_transactions_wuc.ascx";
                       Session["wuc_ID"] = "WUC_previous_20_transactions_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "WUC_administration_wuc$LinkButton_ADMIN_SMS_Settings":
                       Session["wuc_location"] = "sms_settings_wuc.ascx";
                       Session["wuc_ID"] = "WUC_sms_settings_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "WUC_administration_wuc$LinkButton_ADMIN_Department_Setup":
                       Session["wuc_location"] = "department_setup_wuc.ascx";
                       Session["wuc_ID"] = "WUC_department_setup_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   case "WUC_administration_wuc$LinkButton_ADMIN_Terminal_Setup":
                       Session["wuc_location"] = "terminal_setup_wuc.ascx";
                       Session["wuc_ID"] = "WUC_terminal_setup_wuc";
                       Session["Page_First_Load"] = true;
                       break;
                   
                   default:
                       //
                       break;
               }
           }

            //Load the selected user control
            Main_PH.Controls.Clear();
            WUC_default_wuc = new Control();
            WUC_default_wuc = this.LoadControl((string)Session["wuc_location"]);
            WUC_default_wuc.ID = (string)Session["wuc_ID"];
            Main_PH.Controls.Add(WUC_default_wuc);
            base.OnInit(e);
        }

Open in new window


I've deleted a lot of "cases" in the switch above to reduce the size of the code.

So below is one of the problems I'm having:

The aspx page has a menu on the left with links such as ADMINISTRATION, SYSTEM LOGS, USER PREFERENCES - If I click on Administration, the wuc_administration.ascx is loaded into Main_PH. I could have another 10 links from within administration.ascx - 1 in particular is the SMS settings page. Clicking on SMS settings loads:

case "WUC_administration_wuc$LinkButton_ADMIN_SMS_Settings":
                       Session["wuc_location"] = "sms_settings_wuc.ascx";
                       Session["wuc_ID"] = "WUC_sms_settings_wuc";
                       Session["Page_First_Load"] = true;
                       break;

Open in new window


Now if I click on the USER PREFERENCES link on the left menu which loads:

case "LinkButton_MM_Preferences":
                       Session["wuc_location"] = "user_preferences_wuc.ascx";
                       Session["wuc_ID"] = "WUC_user_preferences_wuc";
                       Session["Page_First_Load"] = true;
                       break;

Open in new window


I get a view state error:

Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: 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.

Its driving me insane. I understand Viewstate and the way it works... but I don't see how I could be getting viewstate errors when a user control is removed and a new one is added? This error only occurs when traversing from certain user controls. I could go to the email settings control and then to the user preferences control with no problem.....

I'd appreciate any help on the matter at all!!!
LVL 1
Sunny_KumarAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
Vikram Singh SainiConnect With a Mentor Software Engineer cum AD DeveloperCommented:
Hi,

Would you please check if the following link provides you some solution for your problem:
http://forums.asp.net/t/1274992.aspx

There they says for:

1. EnableEventValidation="false"
2. Set ViewState="false"
3. just redirect the page again (I too don't understand what they mean to say)

Regards,
V.S.Saini
0
 
Dhanasekaran SengodanCommented:
Add following line in  web.config


<system.web>
<pages validateRequest="false" enableEventValidation="false" viewStateEncryptionMode="Never"> </pages>
</system.web>

Open in new window

0
 
Sunny_KumarAuthor Commented:
Hi Dhansmani,

The code above made no difference. I added it as below (as they was already a pages tag)

[code]
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" validateRequest="false"
           enableEventValidation="false" viewStateEncryptionMode="Never">
      <controls>
                        <add tagPrefix="telerik" namespace="Telerik.Web.UI" assembly="Telerik.Web.UI"/>
                  </controls>
            </pages>
[/code]

Thanks for trying to help! Any other suggestions?
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
Vikram Singh SainiSoftware Engineer cum AD DeveloperCommented:
Hi,

If some are working and some not delete all temporary files in TemporaryASP.NET folder. And let us know the result back.

Regards,
VSS
0
 
Sunny_KumarAuthor Commented:
Hi,

I tried deleting the files and it didn't work..... Anything else?
0
 
Sunny_KumarAuthor Commented:
Ok guys I have an interesting update here.

I've attached 3 images:
1. - A screen of sms settings (sms.jpg)
2. - A screen of user preferences (user_pref.jpg)
3. - A screen of user preferences after I swap the 2nd dropdown for a label. (user_pref1.jpg)

Screen 3 is the most important. After the user_preferences_wuc.ascx control kept throwing the viewstate error when you click to it from sms_settings_wuc.ascx, I got rid of the 2nd dropdown from user preferences and replaced it with a label:

[code]
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
[/code]

When I did this, the result was screen 3. There was no viewstate error but the label got populated with the viewstate from the previous sms_settings_wuc.ascx control..... How is this possible?????? Can somebody shed some light on what is happening??
sms.jpg
User-pref.jpg
User-pref1.jpg
0
 
Vikram Singh SainiSoftware Engineer cum AD DeveloperCommented:
Hi,

After reading your whole code and having look on snapshot of your website I reached at some conclusion. Please rectify me if I am wrong at some point. What I am sharing with you is based on my theoretical knowledge of the concept.

Here we go: (Trying to understand your problem and sharing solution)
(1) All your menu items on left side are linkbutton. And you are opening particular user control dynamically on basis of click event of particular button.

(2) Since controls are being created in Page_OnInit event, so it would not create problem of saving ViewState of each dynamic controls created.

(3) On loading Administration control (User Control) the inner controls (such as links & with link click other controls) of Admin are also loading. And here is the doubt or solution.

You said you are having 10 links in Admin usercontrol. So whether these controls are also being created dynamically or are they also user control. If they are also user controls, then it means creation of user control within user control. And I think this is disturbing the tree control hierarchy of controls which is being created when your page is posted back to the server. And since your new controls created in usercontrol are now when posted back are causing problem.

Solution for this could be to clear all viewstate of these controls by method protected void ClearChildViewState ()

And for your last comment problem statement:

When I did this, the result was screen 3. There was no viewstate  error but the label got populated with the viewstate from the previous  sms_settings_wuc.ascx control..... How is this possible?????? Can  somebody shed some light on what is happening??

So for that again my answer would be messing of viewstate of controls. Since your mobile number label is probably name as Label1 and of User preference is also name Label1 (this is my assumption). So since the value of Label1 for sms one is already saved in viewstate and when your control's (user preference) label1 value goes with updated value but there is already saved value of the label1 so it replace it with that one.

All knowledge I shared with you is based on the topic I studied at link:
http://msdn.microsoft.com/en-us/library/ms972976.aspx

Regards,
V.S.Saini
0
 
Sunny_KumarAuthor Commented:
Hi Vs,

To answer your questions:

Points 1,2 and 3 are correct.

But the 10 links you mention are not created dynamically: They are created at design-time like so

[code]
 <div class="admin_a">
                    <asp:LinkButton ID="LinkButton_ADMIN_CompanySetup" OnClick="ajax_cp_admin_Click" runat="server">
                    Company Setup
                    </asp:LinkButton>
                </div>
                <div class="admin_a">
                    <asp:LinkButton ID="LinkButton_ADMIN_Preferences" OnClick="ajax_cp_admin_Click" runat="server">
                    User Preferences
                    </asp:LinkButton>
                </div>
                <div class="admin_a">
                    <asp:LinkButton ID="LinkButton_ADMIN_Languages" OnClick="ajax_cp_admin_Click" runat="server">
                    Language Setup
                    </asp:LinkButton>
                </div>
            <div class="admin_a">
                    <asp:LinkButton ID="LinkButton_ADMIN_Currencies" OnClick="ajax_cp_admin_Click" runat="server">
                    Currency Setup
                    </asp:LinkButton>
                </div>
[/code]

There is only 1 panel on the page where user controls are loaded and that is Main_PH. As you can see above (and below for reference), this panel is cleared of controls during Ajax postbacks and then the correct control is re-added:

[code]
Main_PH.Controls.Clear();
            WUC_default_wuc = new Control();
            WUC_default_wuc = this.LoadControl((string)Session["wuc_location"]);
            WUC_default_wuc.ID = (string)Session["wuc_ID"];
            Main_PH.Controls.Add(WUC_default_wuc);
[/code]

Regarding the re-writing of the label in user_prefences_wuc.ascx when traversing from sms_settings_wuc.ascx.... the id of the Label is user pref is label1... the id of the label in sms_settings is Label_SMS_Number1....

I don't understand why this is happening. The Viewstate from the SMS user control is being loaded into the Viewstate of User Preferences control
0
 
Vikram Singh SainiSoftware Engineer cum AD DeveloperCommented:
Hi,

So we are facing problem of ViewState management (overall). And all this unexpected behaviour of program is due to viewstate mixing up. So we would need to get control to ViewState information of page directly and clean it.

But before that I would like to know from your side. Is there any problem if we clear all values of viewstate explicitly. Also have look on link: http://stackoverflow.com/questions/354195/inconsistent-behavior-with-ajax-and-viewstate-in-net Might you get some idea.

Regards,
VSS
0
 
Sunny_KumarAuthor Commented:
Hi,

I don't think there is any problem clearing viewstate as long as its at the correct point. I.e. When a new control is added as below:

switch ((string)Request.Form["__EVENTTARGET"])
               {
                   case "LinkButton_MM_Inbox":
                       Session["wuc_location"] = "administration_wuc.ascx";
                       Session["wuc_ID"] = "WUC_administration_wuc";
                       Session["Page_First_Load"] = true;
                       break; ..... etc

I'll read that article this morning thank you.

Thank you very much for taking your time to help me. It is very much appreciated!
0
 
Sunny_KumarAuthor Commented:
Hi Vs,

I've looked over that article but I don't see how it applies to my case? That person is looking to utlise the viewstate where as I just want to reset it / wipe it... There doesn't seem to be a method to wipe the viewstate.
0
 
Vikram Singh SainiSoftware Engineer cum AD DeveloperCommented:
Hi,

There is and it is Control.ClearChildViewState Method

Please check link for more details:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clearchildviewstate%28v=VS.71%29.aspx

Regards,
VSS


0
 
Sunny_KumarAuthor Commented:
Hi,

I did actually try that method but it did not make any difference.

I am having some success though. User preferences and Sms settings user controls have the same number of controls inside them. I added a placeholder around the whole of the sms settings user control and it seemed to solve my problems.

For some reason ASP.net is getting confused between user controls even though the user control locations and IDs are completely different. The only thing they have in common is the number of child controls they hold. Encapsulating the sms settings child controls within a placeholder has stopped any errors....

Although this is fixed for now I'd still love to know exactly why ASP.net viewstate was getting confused??
0
 
Sunny_KumarAuthor Commented:
Hi VS,

My solution uses Ajax so redirecting is not an option. View state is needed in my solution too so that is not an option.

And EventValidation is a good thing, I don't want to disable it.
http://odetocode.com/blogs/scott/archive/2006/03/20/asp-net-event-validation-and-invalid-callback-or-postback-argument.aspx

As I said its working now even though viewstate has a bug it seems. Points for being very helpful! I do appreciate your time and effort!
0
 
Sunny_KumarAuthor Commented:
Hi Vs, (and others!)

Just to let you know I have solved this. The problem was this. In my page OnInit method where I load the user control, I was also adding it. This is very wrong apparently as viewstate looks for the old user control after the OnInit method. Viewstate does not know that the control has changed.

To fix this problem I change the onInit method to just load the control and not add it as below:

            WUC_default_wuc = new Control();
            WUC_default_wuc = Page.LoadControl((string)Session["wuc_location"]);
            WUC_default_wuc.ID = (string)Session["wuc_ID"];

The Page_onLoad method is the correct place to load the user control.

protected void Page_Load(object sender, EventArgs e)
        {
            Main_PH.Controls.Add(WUC_default_wuc);
}


And now everything works :) :) I really hope this helps somebody out there. Its caused problems for me for a very long time!
0
 
Vikram Singh SainiSoftware Engineer cum AD DeveloperCommented:
Hi,

So this is called Research & Development. And really on working this question I too learned many new concepts and codes related with AJAX and ViewState.

And yes I searched lot for it on internet but the solution there were also based on developer's experience. It will be really fruitful to anyone reading the whole discussion and finally reaching to the solution.

Happy Coding :-)

Regards,
VSS
0
All Courses

From novice to tech pro — start learning today.