One possible reason for “The state information is invalid for this page…” exception
One of our client was randomly having the ASP.net “The state information is invalid for this page and might be corrupt” error on the pages. The weird thing was that it seems to be random. After some testing, we finally found a pattern and ultimately were able find the root cause of the bug. Though there are various reason for this issues (including some reported ASP.net bugs), but one we found doesn’t seems to be documented anywhere. This only happens during in Microsoft AJAX callback and if you have ASP.net ViewState chunking feature enabled.
Please note that sending ViewState in chunks is a new feature in ASP.net 2.0 and let web administrator control how much information is stored in a single view-state variables. This helps keep site running on some of the old proxy and web-browsers (which have a maximum limit for the hidden field length).
After I found a pattern of the problem, we run the HTTP packet analyzer to view the
AJAX response and found something interesting. It seems that there is a problem with the code handling the ViewState chunked fields on the client-side. It’s not the case that ASP.net AJAX programmers forgot to handle this (come on, they are Microsoft’s programmers, how can they miss so obvious thing), but rather you need a little more complex cycle to break this working. I found that as long as the AJAX call returns the larger or same size of ViewState hidden fields it keep working, the problem arises when the page send the smaller number of ViewState than the previous call (which is quite possible specially on last page of the ASP.net Repeater or Grid results).
Here is how I found this. In the client web.config, the maximum length of the ViewState is set to 8K using following attribute maxPageStateFieldLength=“8192“. Now I went to the application search page, and here is a snapshot of the initial headers.
<div>
<input type=”hidden” name=”__EVENTTARGET” id=”__EVENTTARGET” value=”” /><input type=”hidden” name=”__EVENTARGUMENT” id=”__EVENTARGUMENT” value=”” /><input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=”/wEPDwUKMjEwNzE…S4=” /></div>
As you can see, there is just a single view-state field on the page-load. When I performed a search on that page, page generated an
AJAX call to get the results from the server. Server found the first page of result set (containing 100 items) and this increased the response ViewState size to around 12 KB. Here is how the AJAX response looked like (I captured this using a packet viewer tool):
1|hiddenField|__VIEWSTATEFIELDCOUNT|2|8192|hiddenField|__VIEWSTATE|/wEPDwUKMjEwNzE1…9u|1444|hiddenField|__VIEWSTATE1|LmN..FQ==|
As you can see that this time there were two ViewState fields, but the page rendered correctly and I was able to make another
AJAX calls. So clearly the AJAX handles this growing field scenario very nicely. Now when I navigation to the next page (again using AJAX call), that page has less items (as it was last page) and thus ViewState size was decreased. Here is what was returned as ViewState:
7060|hiddenField|__VIEWSTATE|/wEPD…F8Q==|
As you can see that though the size of view-state is decreased correctly to just one hidden field (enough to have the data), but ASP.net didn’t returned the ViewState maximum size info as the first
AJAX call has. So it seems here is a some problem in the AJAX client implementation and it leaves the ViewState value of existing higher ViewState fields. So when you submit that page or make any other calls, browse sends all the ViewState (including the one related to previous AJAX
call) and thus it invalidate the state and ASP.net throw the exception. Looking at the post data confirmed my assumption. Here is what was being sent to the ASP.net server:
__VIEWSTATE=/wEP…F8Q==
__VIEWSTATEFIELDCOUNT=2
__VIEWSTATE1=LmNv…FQ==
As you can that view-state is still communicating that it has 2 fields hidden fields, while only the first field has a valid and complete data. Of course, the ASP.net validation routine will treat this as a view-state corruption and will throw the error.
In short, though I can dig deep into AJAX client library to fix the issue, but I will leave this off to Microsoft programmers (they get big bucks to do this job). For now I have just disabled the ViewState size limit in the client website and things seems back to normal.
Tags: AJAX, ASP.Net, Exception, ViewState
This entry was posted
on Thursday, November 8th, 2007 at 12:08 am and is filed under ASP.Net.
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.
Please note that solution I discussed above is for a very specific type of issue where the ViewState size change between AJAX calls.
Can you please confirm if you are having the same type of issues? If yes, can you please send me some sample script or source-code?
I have added to the body onLoad the name of the function that contains the code above.The Sys error has disapeared but the error :
the state information is invalid for this page.
is appearing again after I make many clicks which is my main problem.
The full description of my problem is in the thread:
http://forums.asp.net/p/1197823/2078485.aspx#2078485
The only other reason I can think of is that you are trying to reference the ScriptManager before it’s fully loaded and initialized.
To workaround this, try adding this removal script in a JavaScript function and then call that function no the load of the page (add it to the OnLoad event of the Body tag)
Sorry,the xml tags didn’t appear in my previous post so I wrote it again:
The entry which they talk about:
add verb=”GET,HEAD” path=”ScriptResource.axd” type=”System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″ validate=”false”
Is already in my web.config file because I have copied all the settings from the asp.net Ajax web.config file in the installation path.
And about using:
location path=”ScriptResource.axd”
I have added it even that I didn’t use:
deny users=”?”
in the web.config file and it makes no difference.
Is there any thing else I could do to solve the ‘Sys’ is undefined error(To be more clear:It occurs as a javascript error not as an asp.net exception).
The attribute which they talk about:
Is already in my web.config file because I have copied all the settings from the asp.net Ajax web.config file in the installation path.And about adding:
I have added it even that I didn’t use and in the web.config file and it makes no difference.
Is there any thing else I could do to solve the ‘Sys’ is undefined error(To be more clear:It occurs as a javascript error not as an asp.net exception).
Hi,
Try these:
http://geekswithblogs.net/ranganh/archive/2006/11/24/98276.aspx
http://forums.asp.net/t/1040236.aspx
http://geekswithblogs.net/lorint/archive/2007/03/28/110161.aspx
Hi,
I put it in the MasterPage in a script element whatever in the head section or after the body tag I get the error undefined character.Then I changed the ” mark(I was just copying it) so I get the error ‘Sys’ is undefined.
May you help me to solve this problem…
You say add it in the script tag after the body tag. I don’t have a script tag after the body tag.
I have a master page. If I add it on the master page right under the body tag, then I get a ‘Sys is undefined’ error on the page and the __VIEWSTATEFIELDCOUNT is still there. Also, I am using the ToolkitScriptManager, which is contained within a form on the MasterPage. The form is contained within the body.
Don’t add this using the RegisterStartupScript, instead just add it after the body tag in the script tag.
For example, here is how it should appear:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoading(function() {
var f = document.getElementById(“__VIEWSTATEFIELDCOUNT”);
if (f) f.parentNode.removeChild(f);
});
Hope this helps.
I tried adding this script to my page using ClientScript.RegisterStartupScript and ClientScript.RegisterClientScriptBlock, but neither worked.
Ashish,
You can add this in the Script tag anywhere in the body (at start or end of the body tag).
FYI, The script given by Dave simply remove the HIDDEN field which contains the View State fields count when loading the page (first time and after ever AJAX call).
Hi Dave/Syed
Can you guys help me with a detailed explanation as where do we have to write the above peice of code (mentioned by Dave). I am very much new to AJAX and facing a similar problem.
Ashish Yadav
Dave,
Excellent. Thank you for the response and quick solution. It did the job.
You should be able to work around this issue by adding this script to your page:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoading(function() {
var f = document.getElementById(“__VIEWSTATEFIELDCOUNT”);
if (f) f.parentNode.removeChild(f);
});
Basically, it removes the field count hidden field before the request manager processes new hidden fields, thus it remains removed if the new data does not have this field. It leaves the actual __VIEWSTATE# fields in but these would be relatively harmless, since asp.net server-side will ignore them.
Hope that helps. We will of course look at a real fix for this for future releases.