Dynamically turn on page-level tracing from within
the Catch
block of your
exception handler and write to the trace log.
In the code-behind class for the page, use the .NET language of your choice to:
Set Page.Trace.IsEnabled = true
in the
Catch
block of your exception handler.
Write to the trace log by using a Trace.Write
of
the form Trace.Write("Exception",
"Message
“,
exc
)
.
Figure 10-3 shows the appearance of some exception
information in the trace sequence. Example 10-4 through Example 10-6 show the
.aspx
file and VB and C# code-behind files for
the application that produces this result.
ASP.NET processes and displays trace statements only when tracing is enabled. However, what if you don’t want to see the trace log all the time, but only when an exception occurs? The answer is to turn tracing on dynamically for the page. You can then write the exception information to the trace log and debug the problem from there.
Our example that illustrates this solution is rather primitive, in that it simply forces an exception. While this is not something you would normally do in production code, it does allow us to show the infrastructure needed to control tracing at runtime.
When the exception occurs, the
exception handler
enables the trace output by setting
Trace.IsEnabled
to true
. In
order for the exception information to appear in the trace sequence,
you must use a Trace.Write
of the form
Trace.Write("Exception"
,
"Message
“,
exc
)
, where
exc
is the Exception
object defined in the catch
statement.
Additionally, the code limits who sees the trace sequence, something
you might want to consider if you are loathe to show tracing
information to remote users when an exception occurs. Before
activating tracing, the program checks to see whether the application
is being run from the local machine (i.e., the browser making the
request is on the machine serving the request). It does so by using
the Request
object to get the local IP address
from the server variables. It then compares this local address to the
loopback address, a special IP number
(127.0.0.1) that is designated for the software loopback interface of
a machine. If it is not equal to the loopback address, a further
comparison is then made to see if the local IP address from the
server variables is the same as the local IP address that accompanied
the request. The results of the comparison are then used to determine
whether to enable tracing and display the exception information in
the trace sequence.
The URLs for page requests on the local machine can be in the form http://localhost/site/page or http://[server]/site/page (where [server] is the local server name), so it is necessary to check for the loopback IP address as well as the actual IP address. If the page were requested using the server name in the URL, it would not be detected as a local request if the second check were not performed.
Example 10-4. Pinpointing the cause of an exception (.aspx)
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH10TestDynamicPageTracingVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH10TestDynamicPageTracingVB"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Test Dynamic Page Tracing</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmTracing" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Pinpointing the Cause of an Exception (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="LabelText"> <input id="chkOnlyLocal" runat="server" type="checkbox"> Show Only If Request Is Local </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <input id="btnCauseException" runat="server" type="button" value="Cause Exception" /> </td> </tr> </table> </form> </body> </html>
Example 10-5. Code-behind for pinpointing the cause of an exception (.vb)
Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH10TestDynamicPageTracingVB.aspx.vb ' ' Description: This class provides the code behind for ' CH10TestDynamicPageTracingVB ' '******************************************************************************* Imports System Imports System.Collections Imports System.Web Imports System.Web.UI.HtmlControls Imports System.Web.UI.WebControls Imports System.Diagnostics Namespace ASPNetCookbook.VBExamples Public Class CH10TestDynamicPageTracingVB Inherits System.Web.UI.Page 'controls on the form Protected chkOnlyLocal As HtmlInputCheckBox Protected WithEvents btnCauseException As HtmlInputButton '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls on ' the the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal Sender As Object, _ ByVal E As EventArgs) Handles MyBase.Load 'Put user code to initialize the page here End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: btnCauseException_ServerClick ' ' DESCRIPTION: This routine provides the event handler for the cause ' exception button click event. It is responsible for ' causing an exception to demonstrate dynamic tracing '------------------------------------------------------------------------- Private Sub btnCauseException_ServerClick(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles btnCauseException.ServerClick Dim list As ArrayList Try 'force an exception by accessing the list without creating it first list.Add(0)Catch exc As Exception
'enable tracing and output the exception information
If ((Not chkOnlyLocal.Checked) OrElse _
((chkOnlyLocal.Checked) And (requestIsFromLocalMachine( )))) Then
Trace.IsEnabled = True
Trace.Write("Exception", _
"Demonstration of dynamic tracing", _
exc)
End If
End Try End Sub 'btnCauseException_ServerClick '************************************************************************* ' ' ROUTINE: requestIsFromLocalMachine ' ' DESCRIPTION: This routine checks to see if the page request came from ' the local machine. ' ' NOTE: Since requests on a local machine can be in the form ' http://localhost/site/page or http://server/site/page, ' two checks are required. The first is for the localhost ' loopback IP address (127.0.0.1) and the second is for the actual ' IP address of the requestor. '-------------------------------------------------------------------------Private Function requestIsFromLocalMachine( ) As Boolean
Dim isLocal As Boolean
Dim localAddress As String
' Is browser fielding request from localhost?
isLocal = Request.UserHostAddress.Equals("127.0.0.1")
If (Not isLocal) Then
' Get local IP address from server variables
localAddress = Request.ServerVariables.Get("LOCAL_ADDR")
' Compare local IP with IP address that accompanied request
isLocal = Request.UserHostAddress.Equals(localAddress)
End If
Return (isLocal)
End Function 'IsRequestFromLocalMachine
End Class 'CH10TestDynamicPageTracingVB End Namespace
Example 10-6. Code-behind for pinpointing the cause of an exception (.cs)
//---------------------------------------------------------------------------- // // Module Name: CH10TestDynamicPageTracingCS.aspx.cs // // Description: This class provides the code behind for // CH10TestDynamicPageTracingCS // //**************************************************************************** using System; using System.Collections; using System.Web; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace ASPNetCookbook.CSExamples { public class CH10TestDynamicPageTracingCS : System.Web.UI.Page { // controls on form protected HtmlInputCheckBox chkOnlyLocal; protected HtmlInputButton btnCauseException; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { // wire the "cause exception" button event handler this.btnCauseException.ServerClick += new System.EventHandler(this.btnCauseException_ServerClick); } // Page_Load //************************************************************************ // // ROUTINE: btnCauseException_ServerClick // // DESCRIPTION: This routine provides the event handler for the cause // exception button click event. It is responsible for // causing an exception to demonstrate dynamic tracing //------------------------------------------------------------------------ private void btnCauseException_ServerClick(object sender, System.EventArgs e) { ArrayList list = null; try { // force an exception by accessing the list without creating it first list.Add(0); } // trycatch (Exception exc)
{
// enable tracing and output the exception information
if ((!chkOnlyLocal.Checked) ||
((chkOnlyLocal.Checked) && (requestIsFromLocalMachine( ))))
{
Trace.IsEnabled = true;
Trace.Write("Exception",
"Demonstration of dynamic tracing",
exc);
}
} // catch
} // btnCauseException_ServerClick //************************************************************************ // // ROUTINE: requestIsFromLocalMachine // // DESCRIPTION: This routine checks to see if the page request came // from the local machine. // // NOTE: Since requests on a local machine can be in the form // http://localhost/site/page or http://server/site/page, // two checks are required. The first is for the localhost // loopback IP address (127.0.0.1) and the second is for the // actual IP address of the requestor. //------------------------------------------------------------------------private Boolean requestIsFromLocalMachine( )
{
Boolean isLocal;
string localAddress;
// Is browser fielding request from localhost?
isLocal = Request.UserHostAddress.Equals("127.0.0.1");
if (!isLocal)
{
// Get local IP address from server variables
localAddress = Request.ServerVariables.Get("LOCAL_ADDR");
// Compare local IP with IP address that accompanied request
isLocal = Request.UserHostAddress.Equals(localAddress);
}
return (isLocal);
} // IsRequestFromLocalMachine
} // CH10TestDynamicPageTracingCS }