Debug.Assert is one of the greatest tools for developers to use for creating solid, bug free code. The problem with using
Debug.Assert lies when you are writing an ASP.Net web site or Web Service. By default with these types of projects, when an Assertion fails, Visual Studio will log the Assertion message to the Debug Output window. But that’s it, no other type of notification that the Assertion failed. ASP.Net and Web Services do not have any built in ability to break into debug mode when an Assertion fails. This sample creates a dll that once referenced by your ASP.Net or Web Service app, just adding a small block of xml into your web.config file will cause the debugger to automatically break into your code.
A Note on Assertions and this article
In this article, I’m making the assumption that the reader knows the how’s, whys, and when’s to using
Debug.Assert. Unfortunately, Assertions are a commonly misunderstood and misused debugging tool. To find out more on the Assertion, ready chapter 3 of John Robbins ‘Debugging Applications for Microsoft .Net and Microsoft Windows’. This book is an amazing resource on power debugging. Also read everything MSDN has to say about the
Assertions in WinForms and Console Applications
Debug.Assert is one of the greatest tools for developers to use for creating solid, bug free code. When an Assertion fails in a WinForm application, by default, you get a message box (see Figure 1) that shows the Assertion message, the stack trace where the Assertion failed, and an option to break into debug mode on the line of code after the Assertion. If you click the Retry button, the debugger will kick in and let you inspect the values that failed the Assertion.
Enter ASP.Net and Web Services
The problem with using Debug.Assert lies when you are writing an ASP.Net web site or Web Service. By default with these types of projects, when an Assertion fails, Visual Studio will log the Assertion message to the Debut Output window. But that’s it, no other type of notification that the Assertion failed. ASP.Net and Web Services do not have any built in ability to break into debug mode when an Assertion fails.
A brief overview of
A TraceListener class is a class that handles message output for
Trace classes (located in the
System.Diagnostic namespace). The
Trace classes have a static collection object called Listeners, which holds a list of
TraceListener objects. By default this collection holds only one
TraceListener object, the
DefaultTraceListener. The .Net Framework also includes a
TextWriterTraceListener and an
EventLogTraceListener. When you call
Debug.WriteLine, the runtime loops through each
TraceListener in the
Debug.Listeners collection and sends the each one the message that you provided. So if you added both the
TextWriterTraceListener and the
EventLogTraceListener objects to
Debug.Listeners, you’ll get the
Assertion message sent to Visual Studios debug output window, the event viewer, and a text file (You must configure each listener via their constructor, but that is outside the scope of this example).
So what does this have to do with breaking on an Assert?
The solution to this problem is a cool, but extremely simple one. Create your own custom
TraceListener object that will handle breaking into the code. This isn’t exactly what the TraceListener class was designed for, but it suites our needs here very nicely. To do this, create a new library project in Visual Studio and rename the default class to
ASPNetDebugAssert, and have this class inherit from System.Diagnostics.TraceListener. Then override the 4
WriteLine() methods of the
TraceListener base class. In each one of these overridden methods, make a call to
BreakInCode(). The code for
BreakInCode is listed below.
private void BreakInCode()
BooleanSwitch assertSwitch = new BooleanSwitch("BreakOnAssert", "");
This method is the workhorse of the dll (albeit, a very small workhorse indeed!). It first creates a BooleanSwitch object based on a value we’ll later put in the ASP.Net or Web Service’s web.config file. If the
BooleanSwitch is enabled it checks to see if a debugger is attached. If the debugger is attached to the running process, the code calls
Debugger.Break() which will cause Visual Studio to break on the very next line after the
Debug.Assert call. If the debugger is not attached to the running process, the code will try to launch the debugger.
And that’s all there is to it…well, almost. When your code calls
Debug.Assert() in an ASP.Net application and the Assertion fails, the Debug class will loop through each listener in its collection and call the
Write() method on each one. When it calls our custom TraceListener class, the debugger is told to break…and Shazam!!!…the debugger will kick in and stop on the next line of code in your ASP.Net application.
ASPNetDebugAssert listener in the web.config
We’re not quite done here. In order for the
BreakInCode() method to work correctly, we need to put a few things into the web.config file. The following block of xml is what you’ll have to add.
<add name="BreakOnAssert" value="1" />
<trace autoflush="true" indentsize="0">
The first thing in here is a definition for our
BooleanSwitch. The <switches><add> element turns the BooleanSwitch on or off (enabled or disabled). Setting the value attribute to 0 will disable the switch and 1 will enable it (in the case of our custom dll, 1 will cause the debugger to break, 0 will not cause the debugger to break).
The second item in this xml block is the <trace> element. With this element, we can add and remove
TraceListener objects to the Debug.Listeners collection without having to recompile our code. I’ll leave it up to you to read up on these web.config elements in MSDN, but it should be obvious that this example adds our custom
TraceListener to the
So how do I use this?
The final piece to this example is actually calling
Debug.Assert in an ASP.Net application. There are a few things we have to do to piece this all together. First, compile your
ASPNetDebugAssertion library in Release build mode. Then, in your ASP.Net or Web Service project, add a reference to the release version of the dll. (Note: If you compile the ASPNetDebugAssertion dll under debug mode, the debugger will use the debug symbols of our dll and break on the line right after
Debugger.Break is called.). Next, copy and paste the web.config xml block listed above into your ASP.Net project’s web.config file. Be sure to paste it inside the <configuration> element, but OUTSIDE of the <system.web> element.
Once this is done, your project is setup and ready to Assert! Somewhere in the code behind of one of your web forms, add the following lines of code.
private void Button1_Click(object sender, System.EventArgs e)
Debug.Assert(sender == null, "sender obj is null");
string assertTest = "Hey, this worked";
this.TextBox1.Text = assertTest;
When the application is first started, the
Debug class will check the web.config file and look to see if any TraceListeners should be added to its
Listeners collection. Once
Debug.Assert is called, it will send “The assertion worked!!” to each TraceListener, including ours. When our dll is called, the
BreakInCode() method will do its work and the debugger will break on the line of code immediately following the
Debug.Assert. And that’s it!!! You now get debugger breaking when you use Assertions, just like you do (almost) with a WinForm application. If you want to turn the break mode off, just change the
BooleanSwitch definition in the web.config to “0”.