Recipe 10.4 Uncovering Problems Within Web Application Components 10.4.1 Problem You want to identify problems within a component of your web application, but your attempts to do so don't seem to work. When you make a call to Trace.Write in the business object, either you get a compilation error or the debugger jumps right over the call and no output ever appears in the trace sequence. 10.4.2 Solution Import the System.Web namespace and reference the current HTTP context when performing a Trace.Write from within the component. In the component class, use the .NET language of your choice to: -
Import the System.Web namespace. -
Reference the current HTTP context when performing a Trace.Write , as in HTTPContext.Current.Trace.Write . The sample component we've written to illustrate this solution appears in Example 10-7 (VB) and Example 10-8 (C#). Example 10-9 shows the .aspx file used to test the sample component. The code-behind for the test page appears in Example 10-10 (VB) and Example 10-11 (C#). Figure 10-4 shows some sample output, including the resulting trace sequence. Figure 10-4. Trace sequence from testing the component 10.4.3 Discussion In order for Trace.Write to work from within a component, you must be able to access the context for the current HTTP request. The easiest way to accomplish this is to import the System.Web namespace and access the HTTPContext.Current property from within the component. | If a component is not part of your web application, you will need to add a reference to the System.Web.dll assembly in your project. You do this in Visual Studio .NET by selecting the project containing the component in the Solution Explorer. Right-click, and then select Add Reference. In the .NET tab of the dialog box that is displayed, select System.Web.dll from the list of components, click Select, and finally click OK. | | The HTTPContext provides access to the Trace object that allows your application to write trace information, as shown in Example 10-7 (VB) and Example 10-8 (C#). | There is one major caveat to this sample: the disadvantage of referencing the current HTTP context in your component is that it does not allow the component to be used in non-web applications. If you need to share components in web and non-web applications, you may want to consider creating a Listener subclass instead, as described in Recipe 10.5. | | 10.4.4 See Also Recipe 10.5 Example 10-7. The business service class (.vb) Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH10TestWebComponentVB.vb ' ' Description: This class provides a "web" component for demonstrating ' outputting trace information from within a class ' '***************************************************************************** Imports System Imports System.Web Namespace ASPNetCookbook.VBExamples Public Class CH10TestWebComponentVB Private mStr As String '************************************************************************* ' ' ROUTINE: theString ' ' DESCRIPTION: This property provides the ability to get/set the ' string in the object '------------------------------------------------------------------------- Public Property theString( ) As String Get Return (mStr) End Get Set(ByVal Value As String) mStr = Value End Set End Property 'theString '************************************************************************* ' ' ROUTINE: addToString ' ' DESCRIPTION: This routine provides the ability to add the passed ' string to the private string in this object one or ' more times. '------------------------------------------------------------------------- Public Sub addToString(ByVal stringToAdd As String, _ ByVal numberOfCopies As Integer) Dim counter As Integer Dim startTime As DateTime Dim elapsedTime As TimeSpan Dim averageTime As Double 'output trace message indicating the start of the concatenations HttpContext.Current.Trace.Write("In Component", _ "Before performing concatenations") 'concatenation the passed string as requested startTime = DateTime.Now( ) For counter = 1 To numberOfCopies mStr &= stringToAdd Next 'output trace message indicating the end of the concatenations HttpContext.Current.Trace.Write("In Component", _ "After performing concatenations") 'calculate the elapsed time for the string concatenations elapsedTime = DateTime.Now.Subtract(startTime) 'Write average time per concatenation in milliseconds to trace sequence averageTime = elapsedTime.TotalMilliseconds / numberOfCopies HttpContext.Current.Trace.Write("In Component", _ "Aver/concat = " & averageTime.ToString("0.0000")) End Sub 'addToString '************************************************************************* ' ' ROUTINE: New ' ' DESCRIPTION: This constructor creates the object and initializes the ' variables in the object '------------------------------------------------------------------------- Public Sub New( ) 'initialize string in object mStr = "" End Sub 'New End Class 'CH10TestWebComponentVB End Namespace Example 10-8. The business service class (.cs) //---------------------------------------------------------------------------- // // Module Name: CH10TestWebComponentCS.cs // // Description: This class provides a "web" component for demonstrating // outputting trace information from within a class // //**************************************************************************** using System; using System.Web; namespace ASPNetCookbook.CSExamples { public class CH10TestWebComponentCS { private String mStr; //************************************************************************ // // ROUTINE: theString // // DESCRIPTION: This property provides the ability to get/set the // string in the object //------------------------------------------------------------------------ public String theString { get { return(mStr); } set { mStr = value; } } // theString //************************************************************************ // // ROUTINE: addToString // // DESCRIPTION: This routine provides the ability to add the passed // string to the private string in this object one or // more times. //------------------------------------------------------------------------ public void addToString(String stringToAdd, int numberOfCopies) { int counter; DateTime startTime; TimeSpan elapsedTime; Double averageTime; // output trace message indicating the start of the concatenations HttpContext.Current.Trace.Write("In Component", "Before performing concatenations"); // concatenation the passed string as requested startTime = DateTime.Now; for (counter = 1; counter <numberOfCopies; counter++) { mStr += stringToAdd; } // output trace message indicating the end of the concatenations HttpContext.Current.Trace.Write("In Component", "After performing concatenations"); // calculate the elapsed time for the string concatenations elapsedTime = DateTime.Now.Subtract(startTime); // Write average time per concatenation in milliseconds to trace sequence averageTime = elapsedTime.TotalMilliseconds / numberOfCopies; HttpContext.Current.Trace.Write("In Component", "Aver/concat = " + averageTime.ToString("0.0000")); } // addToString //************************************************************************ // // ROUTINE: TestWebComponentCS // // DESCRIPTION: This constructor creates the object and initializes the // variables in the object //------------------------------------------------------------------------ public CH10TestWebComponentCS( ) { // initialize string in object mStr = ""; } // CH10TestWebComponentCS } // CH10TestWebComponentCS } Example 10-9. Code to test tracing in the component (.aspx) <%@ Page Language="vb" AutoEventWireup="false" Trace="True" Codebehind="CH10TestTraceWithinWebComponentVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH10TestTraceWithinWebComponentVB"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Test Trace Within Web Component</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"> Tracing Within Web Components (VB) </td> </tr> </table> </form> </body> </html> Example 10-10. Code to test tracing in the component (.vb) Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH10TestTraceWithinWebComponentVB.aspx.vb ' ' Description: This class provides the code behind for ' CH10TestTraceWithinWebComponentVB.aspx ' '***************************************************************************** Namespace ASPNetCookbook.VBExamples Public Class CH10TestTraceWithinWebComponentVB Inherits System.Web.UI.Page '************************************************************************* ' ' 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 Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim webComponent As CH10TestWebComponentVB 'create the "web aware" component webComponent = New CH10TestWebComponentVB 'add a string to the string in the component 1000 times webComponent.addToString("1234567890", _ 1000) End Sub 'Page_Load End Class 'CH10TestTraceWithinWebComponentVB End Namespace Example 10-11. Code to test tracing in the component (.cs) //---------------------------------------------------------------------------- // // Module Name: CH10TestTraceWithinWebComponentCS.aspx.cs // // Description: This class provides the code behind for // CH10TestTraceWithinWebComponentCS.aspx // //**************************************************************************** using System; namespace ASPNetCookbook.CSExamples { public class CH10TestTraceWithinWebComponentCS : System.Web.UI.Page { //************************************************************************ // // 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) { CH10TestWebComponentCS webComponent = null; // create the "web aware" component webComponent = new CH10TestWebComponentCS( ); // add a string to the string in the component 1000 times webComponent.addToString("1234567890", 1000); } // Page_Load } // CH10TestTraceWithinWebComponentCS } |