Debug Web forms easily with the help of VS.NET

Debugging code is never fun. But the .NET Framework and VS.NET can make debugging Web forms as easy as debugging Windows forms.

The magic of the .NET CLR allows for Web debugging to be practically the same as Windows forms debugging. No more JavaScript alert() commands or Response.Write statements commented out for production. Now we have the power of breakpoints and the Immediate window in VS.NET, as well as new features found in the System.Web namespace designed specifically for debugging.

The breakpoint concept still works in Web forms as it does in Windows forms, but with a few caveats:
  • ·        Your development server must have the remote debugging components installed.
  • ·        You must know approximately where to look for the data.

The second point seems simple, but how often have you stepped through an entire VB application only to find that the problem was a variable incorrectly declared before your breakpoint? Tracing provides a much more global answer to the debugging question.

To enable tracing, add a Trace = “true” attribute to your @Page directive for page-by-page implementation. Optionally, you can enable tracing for an entire application with a <trace> entry in the Web.config.

Turning on the tracing for a page or application gives anyone using the Web page a comprehensive breakdown of the many values and attributes used to keep a Web server running. Some of the information includes:
  • ·        Details of the request
  • ·        A breakdown of the application flow
  • ·        The Control Tree
  • ·        Cookies
  • ·        Headers
  • ·        The Form Collection (if it exists)
  • ·        The Querystring (if there is one)
  • ·        Server variables

The trace information itself is phenomenally helpful in debugging and optimizing, but there's more. Using the System.Web.TraceContext class, we have the opportunity to write to the trace information section of the trace.

As shown in Table A, the TraceContext class is remarkably simple, with two properties and two unique methods.
Table A
IsEnabled Property Similar to the Trace attribute of the @Page declarative
TraceMode Property Defines the order of the parts of the trace output on the screen
Write Method Writes messages to the Trace Information section in black
Warn Method Writes messages to the Trace Information section in red

The two methods are also overloaded, each with a similar pattern. The first method accepts a single string input and simply writes that message to the trace log in the appropriate color. The second accepts two strings and writes a message and a category to the log. This category can be sorted with the TraceMode property. You can also call the Warn method, which accepts a message and category as above, as well as an exception object. It writes the exception information to the trace log along with the other information.

A quick example
For this article, I wrote a simple Web form application that adds two numbers in text boxes and puts them in a label. I have a simple function that adds the numbers and an event handler for the button click to return the result, as shown in Listing A.

If you run the example, you'll see that the event handler is not explicitly described in the trace information. We can fix that by adding a Trace message to the beginning of the add_Click method. Trace is a static class in Web applications and doesn’t need to be instantiated before use:
Trace.Write("Running the add_Click handler");

Notice that when we run the sample now and try to add two numbers, there is an entry for the new trace point, but it has no category. We want function calls to be all in one category, so when we add a trace to the sum method, we give it the “Function” category:
Trace.Write("Function","This is the beginning of the sum method");

We aren’t handling bad input in the above handler. We can use the new Try/Catch block and the TraceContext Warn method to deal with this. This leaves us with the code in Listing B.

If we try to add 4 and d using our simple example, we get the trace information shown in Table B.
Table B
Category Message From
/td> Begin Init End Init 0.000489 0.000489 Begin LoadViewState 0.000795 0.000306 End LoadViewState 0.002007 0.001213 Begin ProcessPostData 0.002434 0.000427 End ProcessPostData 0.002895 0.000461 Begin ProcessPostData Second Try 0.003202 0.000307 End ProcessPostData Second Try 0.003476 0.000274 Begin Raise ChangedEvents 0.003745 0.000270 End Raise ChangedEvents 0.004029 0.000283 Begin Raise PostBackEvent 0.004304 0.000275

Running the add_Click handler 0.008536 0.004232
Error There was a problem in add_Click
Input string was not in a correct format.
  at System.Number.ParseInt32(String s,
NumberStyles style, NumberFormatInfo info)
  at System.Int32.Parse(String s)
  at AspNetDebug.WebForm1.add_Click(Object sender, EventArgs e) in c:\documents and settings\sempf\vswebcache\gryphon\aspnetdebug\
webform1.aspx.cs:line 58

0.010645 0.001913 End Raise PostBackEvent 0.030758 0.004577 Begin PreRender 0.031056 0.000298 End PreRender 0.031398 0.000342 Begin SaveViewState 0.035111 0.003714 End SaveViewState 0.035845 0.000734 Begin Render 0.036148 0.000303 End Render 0.041644 0.005496

Easier than VB6
Tracing ends the confusion of having to use alert() variables or Response.Write to determine what's going on behind the scenes in our Web applications. Combining tracing with the power of breakpoints and the other Visual Studio.NET tools works to make debugging Web forms applications as easy as—or easier than—using Visual Basic 6.

Editor's Picks