/ScriptResource.axd : Invalid viewstate
Yet again I am back to this topic.
Internet Explorer 8 (IE 8) is causing a lot of intermintent "/ScriptResource.axd : Invalid viewstate" errors with our web site. Since our web site makes automatic error logs that send us for the pages with error I have the request information. One thing I noticed was that we are getting a lot of request that look like this:
/ScriptResource.axd?d=vSlJhKauG_vkeppFuk4O%2fseparator.gif
A correct reference to /ScriptResource.axd looks a lot like this:
/ScriptResource.axd?d=KPD5hEMt5pl2DUlO-HtW7uGyz9QToptIaomjT4Xh2Elw9iR4V4XA10Vyl8rymXiSQ2llJ9D-oDEkrTRdelC7CR5Q4yGTQBrdaeyHxDcCQ3w1&t=633251016437037680
Notice that there is a query string token that starts d= with a value that is a encrypted or hashed value. My hunch was that on the page request the web server was sending back HTML somewhat like this:
<script src="/ScriptResource.axd?d=KPD5hEMt5pl2DUlO-HtW7uGyz9QToptIaomjT4Xh2Elw9iR4V4XA10Vyl8rymXiSQ2llJ9D-oDEkrTRdelC7CR5Q4yGTQBrdaeyHxDcCQ3w1&t=633251016437037680" type="text/javascript"></script>However, the d value was encrypted in such a way that browser couldn't parse the token correctly. Maybe the token contained a raw > or a quote? So I started up reflector and start looking in the CLR for the line of code that outputted this string. Note that this is CLR 2.0: I found that line in: Assembly System.WebExtensions.dll, Namespace System.Web.Handlers, in a class called ScriptResourceHandler, which implemented the GetScriptResourceUrl of the System.Web.Handlers.IScriptResourceHandler interface. The code in c# looks like this:
if (assembly.GlobalAssemblyCache) { StringBuilder builder = new StringBuilder(); builder.Append(first.Name); builder.Append(','); builder.Append(first.Version); builder.Append(','); if (first.CultureInfo != null) { builder.Append(first.CultureInfo); } builder.Append(','); builder.Append(HexParser.ToString(first.GetPublicKeyToken())); name = builder.ToString(); } else { name = first.Name; } if (_absoluteScriptResourceUrl == null) { _absoluteScriptResourceUrl = VirtualPathUtility.ToAbsolute("~/ScriptResource.axd"); } str = string.Concat(new object[] { _absoluteScriptResourceUrl, "?d=", ScriptResourceHandler.EncryptString((zip ? (notifyScriptLoaded ? "Z" : "z") : (notifyScriptLoaded ? "U" : "u")) + name + "|" + resourceName + "|" + culture.ToString()), "&t=", second.Ticks });Notice that the first letter of the d value is a flag for requesting zipped and flagging the notification of the script loading, the next part is the assemble name that the resource is in (delimited by a |), then the culture string. This is all sent to Page.EncryptString to encrypt.
internal static string EncryptString(string s) { byte[] bytes = Encoding.UTF8.GetBytes(s); return HttpServerUtility.UrlTokenEncode(MachineKeySection.EncryptOrDecryptData(true, bytes, null, 0, bytes.Length)); }Page.EncryptString does these things: 1) UTF8 encodes the string to a byte array 2) Encrypts the byte array using the Machine Key 3) Calls the UrlTokenEncode method of HttpServerUtility MSDN defines UrlTokenEncode as: Encodes a byte array into its equivalent string representation using base 64 digits, which is usable for transmission on the URL. So I took a look at UrlTokenEncode method, which takes a Byte array and calls ToBase64String(). The output of ToBase64String() then is parsed for characters that would cause problems in a value of a URL querystring parameters. These characters are subsituted for a charcters that are safe for the querystring value. Looking over the character set of Base64 there is upper and lower case alpha, all the numbers, and +, / =. Note: http://www.ietf.org/rfc/rfc1421.txt. In UrlTokenEncode + and / are hanlded correctly. However, Base64 uses the = (equal) as padding. Which means it should only be on the end of the string, and the UrlTokenEncode method handles the = at the end. However, there is a very odd case in the UrlTokenEncode method. If there is an = in the middle of the string Base64 string then an = is outputted. When does Base64 return a = in the middle of the string? And if this is the case would this cause IE not to work correctly? {6230289B-5BEE-409e-932A-2F01FA407A92}
I'm seeing this on some of my sites too.
ReplyDeleteThis is a very detailed article on the root cause of this issue and it is surprising that not many people have visited this. There's post at https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=467062 which, I think, discusses this very issue and it seems is related to IE8 [My site's facing this too]. However the workaround is not working since my pages do have a Content-Type: text/html; charset=utf-8 set.
ReplyDeleteregards
Harish
Well, it seems to me like bug in .net, why it appear only in IE8?
ReplyDeleteAnyone has any luck with this? I'm seeing the same issue as well. Only with IE 8.
ReplyDeleteHere is a sample request that is bad:
2009-08-27 18:25:33 W3SVC1035779783 192.168.2.20 GET /ScriptResource.axd d=v-8ylczdJ9KxecFpVmASrtD7QB1aF409Rqeqq9uxqLbm4HY0bkZWABJyCjZePu2G1qoellspacing= 443 - 69.87.137.139 Mozilla/4.0+(compatible;+MSIE+8.0;+Windows+NT+5.1;+Trident/4.0;+InfoPath.2;+.NET+CLR+2.0.50727;+.NET+CLR+1.1.4322;+OfficeLiveConnector.1.3;+OfficeLivePatch.0.0;+.NET+CLR+3.0.4506.2152;+.NET+CLR+3.5.30729) 302 0 0
you should set the content-type in the http header to utf-8 and text/html
ReplyDeletei did it in the web.config.
it does minify the bug but does not totally resolve it...