If you are using the AJAX Control Toolkit you’ve probably noticed the ToolkitScriptManager server control.

One of the great features of the ToolkitScriptManager that comes with the AJAX Control Toolkit is its ability to combine all client side scripts that needs to be loaded in the browser into one request, thus saving the browser’s need to issue multiple requests to the server and speeding up the process of loading the page.

The URL of that combined request contains a hash code of each script that should be combined, so if you have different combinations of client side scripts due to different combinations of controls you are using from the AJAX Control Toolkit you will have a unique URL for each such request.

“So what’s in it for me?”, you ask.

It’s simple. Since these scripts are only changed when you change the AJAX Control Toolkit version (and that only happens once in a while) and these scripts can be quite large (even when Gziped), they are perfect candidates for being delivered from a Content Delivery Network (CDN).

In short, CDN can make your site faster by delivering static content (i.e. images,scripts,static html files, etc) from a location closer to the user making the request. It does that by performing the request on behalf of the user requesting that resource, caching it for a certain period of time and distributing it to server that are geographically closer to the user.

In most CDN systems you need to change the hostname of the resource you wish to be fetched from a CDN to something that was preconfigured to work with your site. The problem with the AJAX Control Toolkit is that it is the one that renders the link to the combined javascripts and you have no control over it.

Luckily the designers of the ToolkitScriptManager class thought about a hook that allows you to change the handler URL of the combined scripts.

If you’ll set the “CombineScriptsHandlerUrl” property with a URL that refers to a CDN you’ll make these scripts get downloaded through the CDN, thus making your site load faster.

For example, instead of having the combined scripts URL look like this:

MyPage.aspx?_TSM_HiddenField_=ctl00_ScriptManager_HiddenField&_TSM_CombinedScripts_=…

It will look something like this:

http://mycdnsubdomain.mysite.com/MyPage.aspx?_TSM_HiddenField_=ctl00_ScriptManager_HiddenField&_TSM_CombinedScripts_=…

This will actually make a request to the CDN instead of going directly to your site since “mycdnsubdomain.mysite.com” is a domain mapped to the CDN (of course not all CDN networks work exactly like that, but most of them work in this manner where you map a certain subdomain or another domain to the CDN).

It’s a rather quick and easy way to boost your site’s load speed with very little effort. Keep that in mind when you need to optimize the client load side of things.

If you mix and match 32 bit machines/processes with 64 bit machines/processes in an ASP.NET load balanced environment and you are using the AJAXControlToolkit ToolkitScriptManager class you might end up with the following error:

Message: Assembly “AjaxControlToolkit, Version=1.0.10920.32880, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e” does not contain a script with hash code “9ea3f0e2”.
Stack trace: at AjaxControlToolkit.ToolkitScriptManager.DeserializeScriptEntries(String serializedScriptEntries, Boolean loaded)

at AjaxControlToolkit.ToolkitScriptManager.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

The reason is that the request being sent to retrieve the combined javascripts of the control used in the page contains a hash code that is used internally. That hash code is being generated from the script’s name using the default string.GetHashCode function which returns different values for 32 bit and 64 bit processes.

If your 64 bit process creates the javascript include call which contains the 64 bit hash code and the request will eventually reach the 32 bit process/machine you will get this error since the hash value will not be found internally and vice versa.

There is an open issue about this in CodePlex since late January but as of the time of this post, the latest source version in CodePlex doesn’t have a fix for this.