Debug JavaScript in ASP.NET Apps

Your pages need JavaScript, both for logic and UI. But debugging JavaScript code can be a pain, unless you know a few tricks.





Debug JavaScript in ASP.NET Apps

Your pages need JavaScript, both for logic and UI. But debugging JavaScript code can be a pain, unless you know a few tricks.


By Brian Clark


ASP.NET has many advantages over classic ASP in the area of debugging. You can now easily debug your server-side code using the full power of a modern debugger such as Visual Studio .NET. This, along with the introduction of server controls and a postback architecture, has simplified Web-based development. But what about the other half of a Web application, the client-side script?

Although server controls and postbacks have reduced the need for Web developers to interact with JavaScript in an ASP.NET application, many developers are learning that they cannot forget about client-side scripting altogether.


Developers creating Web pages designed to display even a moderate amount of data know the cost of posting back to the server. Using JavaScript to perform simple tasks minimizes the number of roundtrips to the server, potentially avoiding unnecessary queries to the database and reducing the number of times the ViewState is pushed over the wire.


Besides reducing the amount of network traffic, the use of client-side JavaScript enables ASP.NET developers to provide a richer and more interactive experience to the end-user. By moving appropriate functionality from the server to the client you provide the user with instant responsiveness and feedback without the latency implicit in a postback. Balancing functionality between both the client and the server helps reduce some of the load on the Web server, which in turn yields better server response times.


A substantial roadblock to using JavaScript, though, is that it can be difficult to write and debug.


First, IntelliSense for JavaScript is limited at best, which leads to errors in the initial coding stage. Because JavaScript is case-sensitive, the lack of IntelliSense can be aggravating - particularly for developers turning to ASP.NET from a case-insensitive language like Visual Basic.


Also, when a browser's JavaScript error message provides a line number to look at, it often doesn't match the line numbers indicated in the code. The line number will get you in the right area, but after that, it often becomes a guessing game.


Furthermore, if you try putting a breakpoint in the JavaScript in your ASPX, you'll find that when running the project, control will not stop on it and, at best, you may get the not-so-helpful message, "Breakpoint will not be hit, symbols have not been loaded for this document."


Tap into HTML

With Internet Explorer 6 and VS .NET, Microsoft has provided a way to tap into the HTML and JavaScript that Internet Explorer is running, thereby closing the loop in the debugging cycle. By closing this hole developers can now debug their entire application in a single IDE - from client-side script to server-side code, and possibly right through to the database.


Unfortunately for most developers, this won't work without some basic set up. To verify that Internet Explorer is set up correctly, open Internet Explorer, choose Tools | Internet Options. Click the Advanced tab and find Disable script debugging about halfway down the list. Make sure there is no check in the box next to this option. Click OK and close Internet Explorer. The browser is now ready to work with Visual Studio .NET to debug your application.


To begin exploring the basic functions of the debugger, start a new WebForms project and run it without adding any controls or code. When the empty project loads in Internet Explorer, return to Visual Studio and open the Running Documents window by selecting Debug | Windows | Running Documents from the Debug menu.


The Running Documents window will appear docked on the right edge of the IDE. The name of the page, "WebForm1.aspx", will appear in the window. Double-click the page and the HTML rendered to the browser when the ASPX page was evaluated by the server will be shown in a code window on the left, as shown in Figure 1.


Figure 1. The HTML rendered by the ASPX page can be seen by double-clicking the page in the Running Documents window.


The code provided by the Running Documents window is where a developer can set breakpoints and step through the code, just like in server-side code. Stop the project and bring up the form designer.


As an example, a developer might need to create a custom validator that ensures the user has selected a valid item from a dropdown list. Often times a developer does not want users to be able to choose the first item in the list, as this might be a prompt such as "Select an item." (If you are not familiar with custom validators, check out the .NET Framework General Reference for the CustomValidator control at


In this example, create two dropdown lists, one prompting users to "Choose your favorite animal..." (and list various animals). The other should ask the user to "Choose your favorite color..." (and list a few colors).


After configuring a new custom validator on the page to validate the first dropdown, set its ClientValidationFunction to clientvalidate and insert the following validation code into the page's header section (this code will be called by the ASP.NET custom validator control):



The ClientValidationFunction will be called by the CustomValidator each time the value of the dropdown changes.


In the HtmlView, add an OnServerValidation event like this:



Then add the following code, which adds an event handler for ServerValidation. The server-side code is added to the code behind. This code will be called by the ASP.NET custom validator control on browsers that do not support client-side script:


Sub ServerValidation(ByVal source As Object,

  ByVal args As ServerValidateEventArgs)


Dim dl As DropDownList = _

  FindControl(CType(source, CustomValidator) _



 If dl.SelectedIndex = 0 Then

  args.IsValid = False


  args.IsValid = True

 End If

End Sub


Another validator will need to be added and configured in the same way for the second dropdown list. Both validators can point to the same client-side script and server-side event.


After adding a new button labeled Submit, the page will look like Figure 2.


Figure 2. The project after adding the validators, dropdown lists, and button.


Start the project and choose an animal from the animal dropdown. Correctly, the validation error message doesn't appear. Select the first item in the list again and notice that the error message is still not displayed. This is not the expected functionality. The validation function is called each time the value of the dropdown changes. Because the first item in the list is chosen, the error message should be visible.


To find out what is happening in our custom JavaScript code, double-click the Web page in the Running Documents window and put a breakpoint on the first line of code, where we assign the dropdown list. Switch back to Internet Explorer and select another animal name. Execution of the page will break on the line of code selected. From here, a developer can walk through the code as if it were server code. Press F10 to step through the code and into the else statement. This is correct behavior. Press F5 to continue running the code.


Now select the first item in the same dropdown list so that execution stops at the breakpoint again. This time, however, examine the value of dropdown.selectedindex. Highlight the words "dropdown.selectedindex" and hit Ctrl-Alt-Q or drag the text to a watch window. The watch window shows that dropdown.seletectedindex is undefined. The one major ramification of this is that the comparison will never return true, and args.IsValid will never be set to false. That is, regardless of the dropdown's value, validation will never fail.


Change the text in the Quick Watch window to "dropdown" and hit Enter. The watch window now lists all the members of the "dropdown" object. Scrolling to the bottom, you can see the problem: "selectedindex" is not a property of the dropdown. It should really be "selectedIndex", with a capital "I".


Now that the problem is known the code must be updated. Don't try to update the code here, though, because this view of the code is not editable. Remember, this is what the browser sees; switch back to the ASPX HtmlView to change the code.


Make the change and run the project again; this time it works as expected.


Debug Startup Code

Unfortunately, the technique described above breaks down when you try to debug code that executes on start up, such as from a server-side Page.RegisterStartUpScriptBlock method in the page load event. Because the JavaScript code runs as the page loads, you have no opportunity to return to the IDE to set a breakpoint.


Debugging startup script code requires a different method for debugging. There are three ways to debug startup script. First, start your project with F10. Pressing F10 will load your default startup page in the browser and immediately put you in break mode on the first line of JavaScript. You can then set another breakpoint elsewhere in your code, or you can step through line by line until you reach the line of interest.


Next, run the page, let the error occur, then set the breakpoint and hit F5. This method comes in handy when you receive an unexpected error. After the page has loaded in your browser and you get an error or incorrect behavior, open the appropriate Running Documents window and place a breakpoint where you would have wanted execution to stop. Return to the browser and hit F5. Visual Studio .NET will recognize that this is the same page you loaded before and will keep your breakpoint in place. When execution reaches the breakpoint, control will return to the IDE.


Finally, use the debugger keyword. The debugger keyword works just like a breakpoint. When the JavaScript interpreter reaches this keyword, it halts execution and returns control to the IDE.


To demonstrate the power of the debugger keyword, insert the code shown in Figure 3 behind the click event of our Submit button.


Private Sub Button1_Click(ByVal sender As System.Object, _

  ByVal e As System.EventArgs) Handles Button1.Click


    If Page.IsValid Then                             


      Dim sb As New System.Text.StringBuilder()




      Page.RegisterStartupScript("MyStartupScript", _



   End If


End Sub

Figure 3. The code behind the Submit button uses the Page.RegisterStartupScript method to add code that will execute after the page loads in the browser.


Run the project, select values from the dropdown, and click the Submit button. No error message is displayed, but the value in our alert box is not quite what would be expected. Add a "debugger" line and step through the code line-by-line. Add this line after the initial