Debugging JavaScript with Visual Studio
I recently had a situation at work where I had to do some deep debugging of JavaScript. As an ASP.NET developer, I rarely have to hand-write JavaScript now days and when I do it requires little more than some well-placed ‘alert’ calls to diagnose problems. However, this situation was different. We recently started using the ASP.NET AJAX Extensions in our company website. Initially I was excited to try some of the new features but alas my excitement quickly waned when I found that many of the supplied controls did not play well with our website. I should be clear that I’m referring specifically to the ASP.NET AJAX Control Toolkit, a community created set of control extenders that use the AJAX library. I’m only speaking from my own experience, but it quickly became apparent to me that the ASP.NET AJAX Control Toolkit was only half-baked. I had popup controls popping up in the wrong places, watermark controls returning their watermark contents instead of their actual values, and the list goes on. By the time I realized it, it was too late and we had already promised some of the advanced features to our clients. My task today was to figure out why the CollapsiblePanel was no longer working after we moved our code into our test environment. I was going to have to debug some JavaScript… ugg!
At this point I opened up Firefox and went to my favorite new tool: Firebug. Firebug is an add-on that no web developer should be without. You can view and manipulate CSS styles in real time, debug JavaScript, profile the performance of the page and more. In short, I absolutely love it. But wouldn’t you know it, the page rendered just fine in Firefox. Darn, this was an IE specific bug.
Internet Explorer has a similar toolbar to Firebug called funny enough, The Internet Explorer Developer Toolbar but it’s a little like Firebug’s poor redheaded stepchild. It’s nowhere near as feature-rich as Firebug but it does show you just how IE views the page. With the toolbar I could see what was happening but not why because it has no JavaScript debugger. I was going to have to debug with Visual Studio.
The difficult thing about debugging the ASP.NET AJAX Extensions is that it makes heavy use of a ScriptResource HttpHandler meaning that the scripts don’t actually reside as files in your project, but as embedded resources in the toolkit assembly. That’s going to make it difficult to set breakpoints unless we do something. Follow along:
Debugging the ASP.NET AJAX Control Toolkit:
1. Add the ScriptPath attribute to your ScriptManager tag like so:
<ajax:ScriptManager ID="scriptManager" runat="server" ScriptPath=“~/Scripts”> </ajax:ScriptManager>
The ScriptPath attribute will tell the ScriptManager to use physical files instead of the embedded resources. In my case I store my scripts in a folder off the root called “Scripts” but you can put in anything you like.
2. Reload the page you want to debug. In places where you used to see tags like this:
<script src="/WebSite/WebResource.axd?d=XA2BkqE-LwYXxVf0n2mXK2XAdG_QFcKMKrRInGC6YSY1&t=633197367748281250" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=Iri9CC7qSWXFN2_aTKjQKwLnpRI4cKqTtmQv1hu3zGm-YMLmfWhFlYiV2mPwWspBxypnHaofKRgoijmrKIU0oHzFNVXVg0nAsVyTayIKAKg1&t=633090325783593750" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaohKdlhZuNyGl8KHZ4sIZ7zFNfkyHcKc9-0j36SIjWLQmeZH7KaotTn254GFgyUcmEE1&t=633167421400000000" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaohlHX_jqyWmGxF0KIO_NosItiAFMUSxx-xgPKWDHGb5cANtyv1pGg92wJLJdKEZYXVnyhM-xOuy0CHXLYSXZ_Ke0&t=633167421400000000" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaoj-0Xof4cz_Mo2Q2xZiZS7u4vyDSGmbsPCcqqWH6VWuEA2&t=633167421400000000" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaohxC5tfwMOMd7aFOPQYpOgR4lIqclb3saFVJjSCMh__UQ2&t=633167421400000000" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaoj-6c0WDPbuoYpoC-jQANPcQKfXNP-djlqPW9jRbsVhvw2&t=633167421400000000" type="text/javascript"></script> <script src="/WebSite/ScriptResource.axd?d=fALaqp9y-7-IOaUX4VcDx3GePXBu4TNCvYH8qiFIaohTsCCXJk5TS7mTDUSblFwA5fRTi-9mreMmd7lJ4OFw2KSaEwzcCSktqjomC5F46zp1I9XaG5PYpAetUAatjj3g0&t=633167421400000000" type="text/javascript"></script>
you should now see tags like this:
<script src="/WebSite/WebResource.axd?d=XA2BkqE-LwYXxVf0n2mXK2XAdG_QFcKMKrRInGC6YSY1&t=633197367748281250" type="text/javascript"></script> <script src="../Scripts/System.Web.Extensions/1.0.61025.0/MicrosoftAjax.debug.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.ExtenderBase.BaseScripts.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.FilteredTextBox.FilteredTextBoxBehavior.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.Common.Common.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.Compat.Timer.Timer.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.Animation.Animations.js" type="text/javascript"></script> <script src="../Scripts/AjaxControlToolkit/1.0.10606.0/AjaxControlToolkit.CollapsiblePanel.CollapsiblePanelBehavior.js" type="text/javascript"></script>
3. Now simply copy the JavaScript files from the source toolkit source code to the locations above and we should now have physical files to work with. The paths and names in the toolkit source are a little different than above, but you should find it trivial to locate the file and copy it to the new path with the correct name.
Now we have physical files that work exactly the same as the embedded ones.
4. To get debugging working you also need to make sure that it’s properly enabled in Internet Explorer. You can do that by going to the Tools->Internet Options->Advance screen and un-checking the item “Disable script debugging (Internet Explorer)”.
5. Open any JavaScript files you want to debug in Visual Studio and set your breakpoints.
6. Start debugging by hitting F5 in Visual Studio and you should be good-to-go. If you’re like me though and prefer to attach to a running process it’s just as easy. From Visual Studio select Debug->Attach to Process…. In the Attach to Process dialog, change the “Attach to:” option to “Script code”, select the IE process you want to debug and finish by clicking Attach.
Some Things to Remember:
I found that hovering my mouse over JavaScript variables in the debugger to get their value didn’t always work but that I was able to get their values easily through the Immediate Window. You might also want to re-enable the “Disable script debugging (Internet Explorer)” option in IE when you’re done because every website that has JavaScript errors is going to start asking you if you want to debug it.
Resources:
- AJAX Control Toolkit - The project page and source code for the toolkit.
- Damian Mehers Blog - How to use the
ScriptPathattribute. - Mike Ormond’s Blog - How to setup JavaScript debugging in Visual Studio.
- Firebug - The must-have Firefox add-on for web developers.
- Internet Explorer Developer Toolbar - The Firebug knockoff for IE.
P.S. - In case you’re wondering, the bug turned out to be that somewhere along the line my web page got change from “XHTML 1.0 Transitional” to “HTML 4.0 Transitional”. Once I changed it back, the CollapsiblePanel began behaving again.
December 12th, 2007 at 9:03 am
Thanks for the post. My page had a ToolkitScriptManager which I had to change to a normal scriptmanager to get it to work but got it going in the end. Thanks again.