Why we get the exception “Failed to load viewstate”
Background
When we try to add controls dynamically during the post-back request for an ASPX page, we may get below 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.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: 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.
Source Error:
|
Stack Trace:
|
Actually, we can reproduce this kind of exception easily with below code snippet:
protected void Page_Load(object sender, EventArgs e)
{
Button btn4PostBack = new Button();
btn4PostBack.Text = "Click me to POST back to web server ";
form1.Controls.Add(btn4PostBack);
if (!IsPostBack)
{
GridView gv = new GridView();
form1.Controls.Add(gv);
}
else
{
Button btnClickMe = new Button();
btnClickMe.Text = "Click me";
form1.Controls.Add(btnClickMe);
}
}
So the question is: why we get above exception while we try to add controls dynamically?
Cause
As we know, we use VIEWSTATE which is stored at a hidden filed called _VIEWSTATE to restore controls status for the post-back Request, just like below:
“…
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTcwMzIxOTA3Ng9kabcAw9kFgICAw9kFgJmabcwrAA0AZBgBBRVXZWJVc2VyQ29udHJvbDEkY3RsMDAPZ2S95O9gAO7zi4zDomJbUayuj3/4Fw==" />
</div>
…
”
At the same time, the controls’ status is stored with a kind of ArrayList which consist of PAIR or Triplet. Let’s saying:
Position: Index 0, Type: Button
Position: Index 1, Type: literal
Position: Index 2, Type: RadioButton
So for the current POST-BACK request, when you try to add controls dynamically, the newly added control will be validated and see if it matches the control stored in the previous VIEWSTAT. If not, you will get above exception.
Resolution
Option 1:
You can disable the VIEWSTATE of this ASPX page :
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind=" #####.aspx.cs" Inherits="#####" EnableViewState="false"%>
Option 2:
You can also change your source code to make sure the controls added during a post-back must match the type and position of the controls added during the initial request.
References
1) Understanding ASP.NET View State
https://msdn.microsoft.com/en-us/library/ms972976.aspx
2) Triplet Class
https://msdn.microsoft.com/en-us/library/system.web.ui.triplet(v=VS.80).aspx
Winston from APGC team
Comments
- Anonymous
May 03, 2012
Tôi cũng gặp tình trạng tương tự mà chưa có phương án giải quyết triệt để.http://www.bigc24h.com - Anonymous
May 17, 2013
Thank you so much for this article... Its perfectly working fine... thanku again - Anonymous
November 21, 2013
i did a change the propertie EnabledViewState for false in FormView and works fine. - Anonymous
December 07, 2014
Thanks a lot ..it is working without showing error again - Anonymous
February 21, 2016
Could you just tell me where would I need to update the change?