I l @ ve RuBoard |
Now let's take a look at the actual implementation of the Trace class, shown in Listing 13.3. We'll just examine the VB version of the class prototypes ; the C# or JScript versions can be viewed using the class browser application that ships with the .NET SDK (or available at http://docs.aspng.com/quickstart/aspplus/doc/classbrowser.aspx), under the System.Web.TraceContext object. Listing 13.3 VB prototype for the Trace class.Public Warn (category As String, message As String) Public Warn (category As String, message As String, errorInfo as Exception) Public Write (category As String, message As String) Public Write (category As String, message As String, errorInfo as Exception) Note that both Trace.Warn and Trace.Write are examples of overloaded methods . That is, more than one method definition exists for a given name , and the one that is used depends on the signature, or number and type of parameters, that is used to invoke the method. In the case of these two methods, the effect is that the errorInfo parameter is essentially optional ”whether or not it is used affects the method's behavior, but it is not a required parameter. The category parameter is used to group a set of messages together, for instance, if you wanted to signal that you were in a particular subroutine, or a particular iteration of a loop. The message string is your actual message that you are outputting ”this can be anything you like. If your program encounters an exception that you handle, you can use Trace or Warn to report that exception, using the errorInfo parameter. Let's look at how each of these parameters is used in an example. Listing 13.4 demonstrates how you might make use of tracing to debug a function, by displaying the status of the function in different states and iterations. Listing 13.4 Source code for tracedebug.aspx.<%@ Page Language="VB" Trace="False" %> <script runat="server" language="vb" Option="Strict"> Function Factorial (base as Integer) as Integer If base <=0 Then Trace.Warn("Factorial", "Invalid base value: " & base) Exit Function ElseIf base = 1 Then Trace.Write ("Factorial", "Exit condition met, returning.") Return base Else Trace.Write("Factorial","Recursing, new value: " & base-1) Return base * Factorial(base-1) End If End Function </script> <html> <head> </head> <body> <% Response.Write(Factorial(-1) & "<br>") Response.Write(Factorial(5) & "<br>") %> </body> </html> This code produces the output displayed in Figure 13.2. Figure 13.2. Tracing output.
Notice the difference in effect between Warn and Write (you may need to view this page yourself to see the difference, because the black-and-white figure probably doesn't demonstrate it). Warn displays the message line in red, whereas Write displays it in black. This is really the only difference between the two commands, but it does allow you to differentiate between simple logging and more important messages. System.Trace.TraceContextWhen you use Trace , you are using an instance of the TraceContext class defined in the System.Web namespace. TraceContext supports the following two properties:
IsEnabled is provided so that debugging logic beyond simple trace statements can be encapsulated in if statements and only executed when the page is actually in debug mode. For example, if you looped through a collection and output the contents using Trace , you would want to enclose the entire loop in an If Trace.IsEnabled Then statement so that you wouldn't have the overhead of the loop when the application was not being debugged . TraceMode determines the order in which tracing output is displayed. By default, trace output is listed sequentially, in order of execution. This corresponds to the TraceMode value of SortByTime . The other option for TraceMode is SortByCategory , which lists trace output sorted by category first, and then by time. TIP In Custom Components, you can use tracing if you reference the System.Web namespace and use the HttpContext.Current object to get a reference to the current context. For example: System.Web.HttpContext.Current.Trace("category","message"); Exception HandlingIn Classic ASP with VBScript, error handling was rudimentary at best. It consisted of two states, ON and OFF, which were controlled by the statements On Error Resume Next and On Error Goto 0 . JScript ASP was a bit better than its counterpart , having added support for Try...Catch in a later version of the scripting engine, but no such improvement was ever seen in VBScript, which remained Microsoft's default language for building Active Server Pages. Try and Catch blocks trace their origins back to C/C++, after which JavaScript/Jscript was modeled . Enter ASP.NET, with which Microsoft has finally incorporated powerful exception-handling features into all the languages used, including VB.NET. It now becomes possible to do things that were difficult or extremely awkward in classic ASP. Further, when combined with Trace and some System.Diagnostics libraries, it is possible to build error handling into ASP.NET pages that would only have been possible in compiled COM objects with classic ASP pages. Listing 13.5 demonstrates this capability. The results of Listing 13.5 are displayed in Figure 13.3. Figure 13.3. Built-in error handling.
Listing 13.5 Source code for logerror .aspx.<%@ Page Language="VB" Trace="True" %> <script runat="server" language="vb" Option="Strict"> Function Factorial (base as Integer) as Integer If base <=0 Then Err.Raise(-1,"Factorial","Invalid value for Factorial") ' 'we forget our exit condition here... ' 'ElseIf base = 1 Then ' Trace.Write ("Factorial", "Exit condition met, returning.") ' Return base Else Trace.Write("Factorial","Recursing, new value: " & base-1) Try Return base * Factorial(base-1) Catch E As Exception Trace.Warn ("Factorial: " & base, "Error in Factorial call.", E) End Try End If End Function </script> <html> <head> </head> <body> <% Try Response.Write(Factorial(-1) & "<br>") Catch E As Exception Trace.Warn ("Main: -1", "Error calling Factorial", E) End Try Try Response.Write(Factorial(5) & "<br>") Catch E As Exception Trace.Warn ("Main: 5", "Error calling Factorial", E) End Try %> </body> </html> Note that in this example, we have broken the Factorial function such that it has no valid exit condition, but rather raises an error when an invalid value is sent to it. Demonstrating the usage of the Try and Catch statements in VB, we cause this exception to be raised both directly from the main page execution as well as from within a recursive call to the function. If you're unfamiliar with Try , Catch , and Finally , consider this really quick explanation. Basically, you want your code to attempt (or try) to execute whatever is in the Try block. However, if any errors are thrown, they are caught by the Catch block (with a reference to the exception passed in, E in Listing 13.5). Although not demonstrated in this code listing, the Finally block provides a third block of code that is executed regardless of whether there were any errors encountered in the Try block. The Finally block is most often used to execute any "cleanup code" that is required to release resources used in the Try or Catch blocks. Getting back to the example in Listing 13.5, in both Try blocks, when the exception is encountered, we trap it with a Catch statement and use Trace.Warn to display the error information. By passing the exception, E , to the Warn (or Write ) method of Trace , the details of the exception are written out in addition to whatever message is sent in the message parameter. Essentially, this is the same as if the exception's ToString method were called and appended to the method parameter. This provides a simple way to output detailed error information for debugging purposes. Application-Level DebuggingIn addition to page-level tracing, we can also enable or disable tracing for our entire application. This is done through the web.config utility that was discussed in detail in Chapter 10, "ASP.NET Applications." By adding the setting described in Listing 13.6, we enable tracing for our entire application. The various settings and their effects are described in Table 13.1. Note that this setting must be made in the Web.config file located in the application root, not in a subdirectory's Web.config. Listing 13.6 The web.config settings to enable application tracing.<!--Sample trace setting --> <trace enabled="true" localOnly="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" /> Table 13.1. The web.config Settings
Application-level tracing allows you to view trace output for every page in your application, either on each page or through a centrally organized page called Trace.axd. The Trace.axd page does not actually correspond to a file on the Web server, but rather makes use of an HTTP handler to detect the request for this file and respond with the dynamically generated tracing information. HTTP handlers are similar to ISAPI extensions, and are a fairly advanced technique that is beyond the scope of this book. You can learn more about them at http://docs.aspng.com/quickstart/aspplus/doc/httphandlers.aspx. An example of a Trace.axd file is shown in Figure 13.4. Figure 13.4. A Trace.axd file.
The Trace.axd file has two views. The default view displays a list of up to ( requestlimit ) pages that have trace information. Clicking on the View Details link for any of these pages brings up its trace output, which is identical to the trace output that you saw in Figure 13.2 for a page using page-level tracing. |
I l @ ve RuBoard |