views:

1532

answers:

1

I'm getting a weird error from my sites ever since upgrading to Windows 2008 64-bit. I have most of my app pools running in 64-bit mode (all but one, used for a legacy ASP.NET 1.1 application). On the sites that are running on 64-bit, I've been getting errors from ASP.NET AJAX.

Exception information:
   Exception type: System.NotSupportedException
   Exception message: Assembly "AjaxControlToolkit, Version=3.0.20820.16598, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e" does not contain a script with hash code "e2e86ef9".

Request information:
   Request URL: http://site.com/page.aspx?_TSM_HiddenField_=ctl00_ctl00_elScripto_HiddenField&_TSM_CombinedScripts_=%3B%3BAjaxControlToolkit%2C+Version%3D3.0.20820.16598%2C+Culture%3Dneutral%2C+PublicKeyToken%3D28f01b0e84b6d53e%3Afr-FR%3A707835dd-fa4b-41d1-89e7-6df5d518ffb5%3Ae2e86ef9%3A9ea3f0e2%3A9e8e87e9%3A1df13a87%3Ad7738de7

Thread information:
   Thread ID: 21
   Thread account name: NT AUTHORITY\NETWORK SERVICE
   Is impersonating: False
   Stack trace:    at AjaxControlToolkit.ToolkitScriptManager.DeserializeScriptEntries(String serializedScriptEntries, Boolean loaded) in c:\AjaxControlToolkit_Admin\Release\AjaxControlToolkit\ToolkitScriptManager\ToolkitScriptManager.cs:line 534
  at AjaxControlToolkit.ToolkitScriptManager.OutputCombinedScriptFile(HttpContext context) in c:\AjaxControlToolkit_Admin\Release\AjaxControlToolkit\ToolkitScriptManager\ToolkitScriptManager.cs:line 264
  at AjaxControlToolkit.ToolkitScriptManager.OnInit(EventArgs e) in c:\AjaxControlToolkit_Admin\Release\AjaxControlToolkit\ToolkitScriptManager\ToolkitScriptManager.cs:line 198
  at System.Web.UI.Control.InitRecursive(Control namingContainer)
  at System.Web.UI.Control.InitRecursive(Control namingContainer)
  at System.Web.UI.Control.InitRecursive(Control namingContainer)
  at System.Web.UI.Control.InitRecursive(Control namingContainer)
  at System.Web.UI.Control.InitRecursive(Control namingContainer)
  at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The error appears to be a known issue in CodePlex but that doesn't help me much. Here's a link explaining the issue: http://dotnetdebug.net/2008/05/25/ajaxcontroltoolkit-toolkitscriptmanager-stringgethashcode-and-mixing-32bit-and-64bit-machinesprocesses/

I am not using load balancing and am wondering why my application would be switching between 32-bit and 64-bit modes.

Could it be that the DLLs must be compiled for a 64-bit architecture or something like that? Are there any weird issues I should be aware of that could be causing this issue for me?

+2  A: 

It looks like the String.GetHashCode() result changes based on what instruction set the dll has been compiled for. I can't explain why this happens within the framework when your .NET 2.0+ app pools are all 64-bit but there's a solution you can try if you're willing to grab the latest source off codeplex and change a few lines in the ToolkitScriptManager.

I don't know why an official fix hasn't been submitted based on the comments available--maybe because all the solutions are as ugly as mine?

I've attempted to fix it by using the SHA1 hash routine as described in one of the comments--so first I created a static instance of the SHA1Managed provider in the ToolkitScriptManager class as shown below:

public class ToolkitScriptManager : ScriptManager
{
    private static System.Security.Cryptography.SHA1Managed s = new System.Security.Cryptography.SHA1Managed();

...

then there are two places where the string hash code was being used that I commented out and replaced--once in the SerializeScriptEntries function:

//serializedScriptEntries.Append(scriptEntry.Name.GetHashCode().ToString("x", CultureInfo.InvariantCulture));
serializedScriptEntries.Append(Convert.ToBase64String(s.ComputeHash(System.Text.Encoding.UTF8.GetBytes(scriptEntry.Name))));

and then once in the DeserializeScriptEntries function:

//string hashCode = resourceName.GetHashCode().ToString("x", CultureInfo.InvariantCulture);
string hashCode = Convert.ToBase64String(s.ComputeHash(System.Text.Encoding.UTF8.GetBytes(resourceName)));

Maybe a simpler method would allow us to just access the 64-bit GetHashCode method for serializing this string so that we get the same results for 32-bit and 64-bit calls...

Looks promising. I don't want to run my own instance of the toolkit manager but would be happy to vote for this solution on so that it would get rolled into the main product.
Jason Kealey