7.2. TracingTracing is an easy way to determine what is going on in your program. Back in the days of classic ASP, the only way to trace what was happening in your code was to insert Response.Write statements in strategic places. This allowed you to see that you had reached a known point in the code and, perhaps, to display the value of some variables . The big problem with this hand-tracing technique, aside from the amount of work involved, was that you had to laboriously remove or comment out all those statements before the program went into production. ASP.NET provides better ways of gathering the trace information. You can add tracing at the application level or at the page level. With application-level tracing , every page is traced, and with page-level tracing , you choose the pages to which to add tracing. 7.2.1. Page-Level TracingTo add page-level tracing, modify the Page directive at the top of the .aspx page, by adding a trace attribute and setting its value to true , as follows : <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Trace="true" %> When you view this page, there will now be tables at the bottom that contain a wealth of information about your web application. Select a book from the drop-down list and you will see something like Figure 7-2. Figure 7-2. Trace resultsThe top section, labeled Request Details, shows basic information, including the SessionID, the Time of Request, Request Type, and Status Code (see Table 7-1). Every time the page is posted to the server, this information is updated. If you change the selection (remember that AutoPostBack is set to TRue ), you will see that the Time of Request is updated, but the SessionID remains constant. Table 7-1. Status codes
The next section, labeled Trace Information, is the trace log , which provides lifecycle information. This includes elapsed times, in seconds, since the page was initialized (the From First(s) column) and since the previous event in the lifecycle (the From Last(s) column). You can add custom trace information to the trace log as explained later in the chapter. The next section in the trace, under the heading Control Tree, lists all the controls on the page in a hierarchical manner, including the name of the control, its type, and its size in bytes, both on the page and in the ViewState state bag . This is followed by Session and Application State summaries, and itemizations of the Cookies and Headers collections. Finally, there is a list of all the server variables. 7.2.2. Inserting into the Trace LogYou can add custom information to the trace output by writing to the TRace object. This object, encapsulated in the traceContext class, exposes two methods for putting your own statements into the trace log: Write and Warn . The only difference between the two methods is that Warn writes to the log in red. The Warn and Write methods are overloaded to take either a single argument, two arguments, or two strings and an exception object, as the following cases illustrate :
To see this in action, add the highlighted code from Example 7-3 to the code-behind file in your sample web site, DebuggingApp. Example 7-3. Writing to the Trace objectprotected void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here Trace.Write("In Page_Load"); if (! IsPostBack) { Trace.Write("Page_Load", "Not Postback."); // Build 2 dimensional array for the lists // First dimension contains bookname // 2nd dimension contains ISBN number string[,] books = { {"Programming C#","0596001177"}, {"Programming ASP.NET","1234567890"}, {"WebClasses From Scratch","0789721260"}, {"Teach Yourself C++ in 21 Days","067232072X"}, {"Teach Yourself C++ in 10 Minutes","067231603X"}, {"XML & Java From Scratch","0789724766"}, {"Complete Idiot's Guide to a Career in Computer Programming","0789719959"}, {"XML Web Documents From Scratch","0789723166"}, {"Clouds To Code","1861000952"}, {"C++: An Introduction to Programming","1575760614"}, {"C++ Unleashed","0672312395"} }; // Now populate the lists. int i; for (i = 0; i < books.GetLength(0); i++) { // Add both Text and Value ddlBooks.Items.Add(new ListItem(books[i,0],books[i,1])); } } } protected void ddlBooks_SelectedIndexChanged(object sender, System.EventArgs e) { // Force an exception try { int a = 0; int b = 5/a; } catch (System.Exception ex) { Trace.Warn("UserAction","Calling b=5/a",ex); } // Check to verify that something has been selected. if (ddlBooks.SelectedIndex != -1) { lblDdl.Text=ddlBooks.SelectedItem.Text + " ---> ISBN: " + ddlBooks.SelectedItem.Value; } } The first message is added in the Page_Load method to signal that you've entered that method: Trace.Write("In Page_Load"); The second message is added if the page is not a postback: if (! IsPostBack) { Trace.Write("Page_Load", "Not Postback."); This second message is categorized as Page_Load ; using a category can help you organize the trace output. The effect of these two Write statements is shown in Figure 7-3. Figure 7-3. Two Trace.Write outputsThe third message is added to demonstrate the process of inserting an exception into the error log. The ddlBooks_SelectedIndexChanged event handler now contains code to force an exception by dividing by zero. The code catches that exception and logs the exception with a trace statement, as shown by the following code fragment: try { int a = 0; int b = 5/a; } catch (System.Exception ex) { Trace.Warn("UserAction","Calling b=5/a",ex); }
The output from this TRace statement is shown in Figure 7-4. Figure 7-4. Trace.Warn outputBecause this trace statement was written calling the Warn method rather than the Write method, the trace output appears in red onscreen (though not in your copy of this book). Notice that string you passed in, Calling b=5/a , is displayed, followed by an error message extracted automatically from the exception object. Implementing Trace statements is easy, and when it is time to put your page into production, all these statements can remain in place. The only modification you need to make is to change the TRace attribute in the Page directive from true to false . 7.2.3. Application-Level TracingApplication-level tracing applies to all the pages in a given web site. It is configured through the web.config file, which will be described more fully in Chapter 18. The web.config file is typically located in the root directory of the web site. If there is a web.config file in a subdirectory of the application root, then that copy will apply only to the pages in that subdirectory and in the subdirectories under it. If tracing is enabled application-wide from the root directory, tracing will be applied across the application uniformly. The exception is when a specific page has a contradictory page directive, which supersedes the application directive. Web.config is an XML file that consists of sections delimited by tags. The trace configuration information is contained in the <trace> section within the <system.web> section, which is contained within the <configuration> section.
A typical trace configuration snippet will look something like Example 7-4. Example 7-4. Trace code snippet from web.config<?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0" > <system.web> . . . <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" /> You can edit the web.config file using the ASP.NET Configuration Tool, available by clicking the Website ASP.NET Configuration menu item or the ASP.NET configuration iron at the top of the Solution Explorer in VS2005. Alternatively, you can edit web.config manually by double-clicking on the file in the Solution Explorer. (If the Solution Explorer is not visible, click on the View Solution Explorer menu item.) Alternatively, this file can be edited in any text editor. There are seven possible properties in the <trace> section. These properties appear in Table 7-2. Several of these properties affect the trace viewer, which will be described in the following section. Table 7-2. Trace section properties
7.2.4. Trace ViewerIf application-level tracing is enabled, you can view the TRace log directly from your browser for any application, even across multiple page requests. The trace facility provides a trace viewer , called trace.axd . Aim your browser toward trace.axd as though it were a page in the application, with the following URL, for example: http://localhost/DebuggingApp/trace.axd You will see a summary of all the entries in the trace log, as shown in Figure 7-5. Figure 7-5. Trace viewerClicking on any of the View Details links will bring you to the same page as would be seen in page-level tracing for that page. |