Avoid this tricky conflict between ASP.NET AJAX and jQuery
AJAX, ASP.NET, jQuery By Dave Ward on September 28th, 2008
You have probably already read the great news that Microsoft is going to begin shipping jQuery with Visual Studio and ASP.NET MVC. If not, make sure you take a minute to read the official announcements from both ScottGu and John Resig. This represents a surprising, yet tremendously welcomed change of course for Microsoft.
If you haven’t yet used jQuery with ASP.NET, you’re in for a pleasant surprise. It removes almost all of the pain from client-side development. Coming from an ASP.NET centric perspective, you may find several of my previous jQuery articles useful.
Additionally, I highly recommend the articles that Matt Berseth and Rick Strahl have written on the topic of using jQuery with ASP.NET. I am constantly amazed at the quantity and quality of content that they both generate.
Introductions aside, I’d like to take this opportunity to discuss an incompatibility between ASP.NET AJAX and at least one jQuery plugin, which needs to be fixed.
A simple combination leads to an odd problem
Last month, I came across someone having an odd problem with ASP.NET AJAX and jQuery, on the ASP.NET forums. While using the jDrawer plugin to jQuery, he found that adding an ASP.NET AJAX ScriptManager completely broke jDrawer.
Having never encountered trouble mixing ASP.NET AJAX and jQuery plugins, I was reluctant to place the blame on ASP.NET AJAX until I tried it for myself. However, the problem was readily reproducible by downloading the jDrawer sample and adding a ScriptManager. It immediately went from a working demo to throwing this JavaScript error:
Inspecting the specified section of the jDrawer code revealed this function:
PreloadImages: function() { for (var i in arguments.length) if (arguments[i].type === "array") for (var j in arguments[i]) // Irrelevant image preloading code. else // Irrelevant image preloading code. },
It looks simple enough, but we have a problem here…
Understanding the problem
In JavaScript, every function call is accompanied by a special arguments property which consists of an array of any parameters that the function was called with. This allows for functions with a variable number of parameters, like String.format.
jDrawer’s PreloadImages function is dependent on this arguments property. The property is necessary so that an arbitrary number of image URLs may be passed in for preloading. Unfortunately, the plugin author didn’t quite get the for loop right. He’s using the associative form (foreach), but arguments.length is a Number, not an array.
As I’ve previously covered, one of the nice things that ASP.NET AJAX brings to the table is an assortment of upgrades to JavaScript’s base types. Among them, the Number type is modified to include a format property, the root of this trouble:

Notice that even though the arguments property is an empty array, execution has entered the for loop. The reason for that? The jDrawer code is attempting to iterate over the Number, arguments.length, not the empty array itself.
Normally, this would cause the function to silently abort, since the base Number type has nothing to iterate over. However, ASP.NET AJAX has added a few features to the Number type, giving the faulty code the extended Number type’s properties to iterate over.
Because those certainly aren’t valid keys for the arguments array, execution always fails when line 424 tries to reference arguments[i] for the first time. Basically, it’s attempting to access arguments['format'], which throws the error.
The solution is easy!
The solution is to iterate over the arguments array using a traditional for loop:
PreloadImages: function() { for(var i = 0; i++; i < arguments.length) if (arguments[i].type === "array") for (var j in arguments[i]) // Irrelevant image preloading code. else // Irrelevant image preloading code. },
The troublesome format key is ignored, and the function operates as desired.
As a bonus, fixing the error also fixes the image preloading. Even though it wasn’t causing an error without a ScriptManager on the page, the preloading code in this plugin was never working before.
Conclusion
Don’t get me wrong — nothing this minor could possibly begin to dampen my excitement over jQuery getting this official nod from Microsoft.
However, with today’s news about official jQuery support and Microsoft’s efforts toward peaceful client-side coexistence in general, I think this issue is something that should be addressed if at all possible.
It’s not the ScriptManager’s fault that this happened, but it isn’t a problem unless the ScriptManager is present. Not many developers are going to track down obscure JavaScript errors caused by two third party pieces of code. They’ll see the cause of adding the ScriptManager, the effect of it breaking the page, and logically lay the blame on the ScriptManager (unfairly).
Hopefully, having the problem and solution identified here will mean that anyone who runs into it in the meantime will be able to fix it with a quick Google search.
As mentioned previously, I have several posts on using jQuery with ASP.NET AJAX that may be helpful if you’re just getting started with the combination.
If the topic interests you, be sure that you’re subscribed to Encosia updates via either my RSS feed or its email-based counterpart. More posts on ASP.NET and jQuery are on the way soon.
Similar posts
What do you think? Your comments are welcome.
I appreciate all of your comments, questions, and other feedback, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums instead.
If you're replying to an existing comment, please use the threading feature. To do this, click the "Reply to this" link underneath the comment you're replying to.


mmh. I don’t quite understand this for (var i in arguments.length). How does this make any sense?
As far as I know, it doesn’t make sense.
I think he confused his usages of the for statement in JavaScript, or had some reason to believe that arguments is an associative array (which still wouldn’t work, but gets him a lot closer).
So using this with a ScriptManager causes an error in a method that was already silently failing.
It’s a good thing then, right? :) PreloadImages was never really preloading anything.
I’d say it would be a good thing if it didn’t take down the entire plugin when a ScriptManager is present.
Knowing about the error is helpful for you or I, but not so much for the guy on the ASP.NET forums.
With all of this interoperability talk, seeing ASP.NET AJAX change the behavior of an unrelated jQuery plugin may not be the best foot to put forward. Maybe there’s nothing that can be done, but I thought it was worth mentioning.
Hold on — this doesn’t work for me.
Result — nothing! IE, FF.
The reason “format” is showing up is because AJAX adds a “format” method to the Number prototype, and for..in is (correctly) enumerating items on the argument, which is a number (length). It doesnt touch the arguments array.
But it seems to me the for loop didnt work to begin with anyway?
Right. It’s definitely faulty JavaScript on his part. He should be iterating over the arguments array normally, instead of trying to treat it like an associative array.
What worries me is that it fails silently on its own, but breaks the entire page when a ScriptManager is added. As you can see in that ASP.NET thread, that’s the sort of thing that’s not going to reflect badly on the plugin, but on ASP.NET AJAX (unfairly).
Thank you Dave such great tracking to the issue.
In fact I Like to use both jQuery and ASP.NET AJAX together. Lets say the Basic ASP.NET AJAX Components such as ScriptManager and UpdatePanel.
Sometimes I needed to use UpdatePanel. And in return I needed page client events such as pageLoad, while jQuery “ready” event couldn’t help to recreate/initialize jQuery objects.
I’m looking forward to see how MS will put them all together. This will save us too much pain.
Maybe the right thing to do now is submit a patch with the plug-in’s author?
Cheers, Bertrand
Iterating over anything with the in operator in JS does not belong in library code like jDrawer. It is bound to break as soon as somebody updates Object.prototype. You should send the patch to the author.
@Bertrand and @Malte: Definitely. The plugin author was made aware of the problem several weeks ago.
Great tip, thank you, this will be definitely be helpful for lots of people!
great article, thx
the problem IS the .length reference, but could been just as easily solved by omitting the length property and the code would indeed have ran, like so:
for (var i in arguments)
if ( arguments[i].type === ‘array’ )
[...] omitted for brevity.
However, i completely agree with Malte, javascript intrinsic [objects/types] prototypes should not be extended, no matter how ‘cool’ it is to the author, as it has the nasty habit of breaking consumer’s of the lib’s code.
My team at HP went ’round with this until discovering that Prototype broke with expected behavior in this very fashion, (iteration and associative arrays with ‘enhanced’ behavior on intrinsic types) and caused much refactoring of our ecomm framework while under a tight crunchtime deliverable period in the construction phase of one of our showcase projects.
Either namespace or otherwise alias Instances in your own code, or simply Don’t extend my objects!!!
Just my $.02,
//Chris D.