Tải bản đầy đủ (.pdf) (90 trang)

Beginning ASP.NET 1.1 with Visual C# .NET 2003 phần 7 pptx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.03 MB, 90 trang )


The following code shows the syntax for using the ToString() method of the Convert class:
SomeVariable = Convert.ToString(SomeInteger);
'Convert Integer to String
Try to Break Your Code
This can be a more difficult task than expected. It is often difficult for the developer to anticipate all the
unusual things a user might attempt to do with the application, such as accidentally typing in letters
when numbers are required, or supplying an answer that was longer than anticipated, or even
deliberately trying to break it.
So, when it is time to test your application, try to think like a user who isn't too computer literate. You
can break down your testing strategy into two main approaches:

Be nice to your program: Supply your program with legal values, or values that your program is
designed to expect and handle. For instance, if your program contains an age field, supply only
numbers, not letters. Watch how your program behaves – does it respond as you expect it to
with the legal values supplied to it?

Try to break your program: This is the fun part. Supply your program with illegal values. For
instance, provide string values where integers are expected. This ensures that your program
handles all illegal values appropriately. Depending on the kind of data you are expecting in
your program, you could to do anything from a simple numeric or alphabetic check to a validity
check (such as inserting invalid dates into a date field). If your program spans several pages,
then surf to some of the pages out of the expected sequence.
Both these techniques can be used to help standardize and improve the readability of your code. Many
basic errors can be avoided in this way. However, even if you follow all these suggestions, your code still
can't be guaranteed to be bug-free. Let's look at some of the errors that may plague your code.
Conversion Function Return Datatype
Convert.ToDecimal Decimal
Convert.ToInt16 16 bit signed Integer
Convert.ToInt32 32 bit signed Integer
Convert.ToInt64 64 bit signed Integer


Convert.ToSingle Single
Convert.ToString String
513
Debugging and Error Handling
Sources of Errors
The errors that occur in an ASP.NET page can be grouped into four categories:
❑ Parser errors: These occur because of incorrect syntax or bad grammar within the ASP.NET page.

Compilation errors: These are also syntax errors, but they occur due to statements that are not
recognized by the language compiler, rather than ASP.NET itself. For example, using
If (capital
I) instead of if, or not providing a closing bracket to a for loop, will result in a compilation
error. The difference between the parser error and compilation error is that the parser error
occurs when there is a syntax error in the ASP.NET page, and the ASP.NET parser catches it,
whereas the compilation error occurs when there is a syntax error in the C# code block.

Configuration errors: These occur because of the incorrect syntax or structure of a configuration
file. An ASP.NET configuration file is a text file in XML format, and contains a hierarchical
structure that stores application-wide configuration settings. There can be one configuration file
for every application on your Web server. These configuration files are all named
web.config,
irrespective of the application's name.
There is also a single configuration file called
machine.config that contains information that applies to every application on a single
machine. We will discuss
configuration files in detail in Chapter 15, although we do touch
upon them again later in this chapter.

Runtime or logical errors: As the name implies, these errors are not detected during compilation
or parsing, but occur during execution. For example, when the user enters letters into a field

that expects numbers, and your program assigns that entry to an integer variable, you will get a
runtime error when the code tries to execute. These are also known as logical errors.
Now let's look at some specific examples that fall into the above categories.
Syntax Errors
As the name suggests, these errors occur when there are problems in the syntax of the code. Parser and
compilation errors fall under this category. These are usually the first errors encountered when
developing ASP.NET pages. There are several reasons why these errors occur:

A typo or bad grammar in the code syntax: For example, instead of typing <asp:textbox> for
creating a
TextBox control in your page, you type <asp:textbx>, then the browser shows an
error.

Incorrect code syntax: For instance, when creating a textbox control, you might forget to close the
tag (as
<asp:TextBox id="txtName" runat="server"> when it should actually be
<asp:TextBox id="txtName" runat="server" />)

Combining or splitting keywords between languages: I make this error quite a lot. If you've been
coding in another language and come back to coding in C#, you might forget brackets, or type
keywords in the wrong case.
❑ Not closing a construct properly: This error occurs if we forget to close a construct, such as a for
loop or a nested if statement. Take a look at this example:
if condition1 {
514
Chapter 14
//do this
}
else condition2 {
//do this

if condition2a {
//do this
}
else {
//do this
}
Did you catch the error in the above code? We're missing a closing-bracket. Imagine how difficult it
would be to spot this if we had the above code block set amongst hundreds of other lines of code. It's
another good argument for formatting your code correctly too. If it had been indented, it would have
been easier to spot the error.
Let's look at an example of creating a syntax error (a parser error) and then see how ASP.NET responds
to it.
Try It Out Syntax Error
1.
Open Web Matrix and type the following lines of code into the All Window. Make a spelling
mistake when creating the textbox control, as highlighted in the following code:
<html>
<head>
<title>Syntax Error Example </title>
</head>
<body>
<form method="post" action="syntaxerror.aspx" runat="server">
<asp:TetBox id="txtQuantity" runat="server" />
</form>
</body>
</html>
2. Save this file as syntaxerror.aspx and load the file using a browser. You expect to see a
textbox in the browser, as shown in Figure 14-1:
Figure 14-1
515

Debugging and Error Handling
However, what you actually see is Figure 14-2:
Figure 14-2
How It Works
As the error message clearly states, the ASP.NET parser points to Line 7, and asks us to check the details.
You can see that a spelling mistake exists,
Tetbox instead of TextBox. If you correct the spelling mistake
and rerun the code, you'll get the expected result.
Errors of this kind are very common but are usually quick and easy to fix, since the error message
provides a detailed breakdown of the error and the line on which it occurs.
Now we will look at a syntax error that will generate a compilation error.
Try It Out Generate a Compiler Error
1.
Create a new file called compilationerror.aspx, and type the following code into the Web
Matrix
All window:
516
Chapter 14
<%@ Page language="C#" Debug="true" %>
<script language="C#" runat="server">
public void CompleteOrder(Object sender, EventArgs e)
{
If (txtQuantity.Text == "")
{
lblOrderConfirm.Text = "Please provide an Order Quantity.";
}
else if (Convert.ToInt32(txtQuantity.Text) <= 0)
{
lblOrderConfirm.Text = "Please provide a Quantity greater than 0.";
}

else if (Convert.ToInt32(txtQuantity.Text) > 0)
{
lblOrderConfirm.Text = "Order Successfully placed.";
}
}
</script>
<html>
<head>
<title>Compiliation Error Example</title>
</head>
<body>
<form method="post" action="manualtrapping.aspx" runat="server">
<asp:Label text="Order Quantity" runat="server" />
<asp:TextBox id="txtQuantity" runat="server" />
<br />
<asp:Button id="btnComplete_Order" Text="Complete Order"
onclick="CompleteOrder"
runat="server"/>
<br />
<asp:Label id="lblOrderConfirm" runat="server"/>
</form>
</body>
</html>
2. Save and view the compilationerror.aspx file with a browser. The page displayed is as
shown in Figure 14-3:
517
Debugging and Error Handling
Figure 14-3
How It Works
We typed If at the beginning of our control block instead of if. As expected, when we tried to run the

compilationerror.aspx file in the browser, we got an error message. It tells us we have a compiler
error in
Line 5 and even attempts to tell us how to fix it. (In this case it is rather misleading as it tells us
we are missing a semicolon, when in fact, the
if statement is the part that is incorrect!)
These are just a few common examples of syntax errors. There is no way we could provide a list of all
possible syntax errors that you might encounter, but the good news is that syntax errors are easy to find
and fix.
Logical (Runtime) Errors
The second type of error is the Logical Error. Unfortunately, it is relatively more difficult to find and fix.
Logical errors become apparent during runtime. As the name implies, these errors occur due to mistakes
in programming logic. Some of the more common reasons for these errors are:
518
Chapter 14
❑ Division by zero: This dreaded error that has been around since the days of valve-based
computers. It occurs when your program divides a number by zero. But why in the world do
we divide a number by zero? In most cases, this occurs because the program divides a number
by an integer that should contain a non-zero number, but for some reason, contains a zero.

Type mismatch: Type mismatch errors occur when you try to work with incompatible data types
and inadvertently try to add a string to a number, or store a string in a date data type. It is
possible to avoid this error by explicitly converting the data type of a value before operating on
it. We will talk about variable data type conversion later in this chapter.

Incorrect output: This type of error occurs when you use a function that returns output that's
different from what you are expecting in your program.
❑ Use of a non-existent object: This type of error occurs when you try to use an object that was
never created, or when an attempt to create the object failed.

Mistaken assumptions: This is another common error, and should be corrected during the

testing phase (if one exists). This type of error occurs when the programmer uses an incorrect
assumption in the program. This can happen, for instance, in a program that adds withdrawal
amounts to a current balance, instead of subtracting them.

Processing invalid data: This type of error occurs when the program accepts invalid data. An
example of this would be a library checkout program that accepts a book's return date as
February 29, 2003, in which case, you may not have to return the book for a while!
While this is far from being a complete list of all possible logical errors, it should give you a feel for what
to look out for when testing your code.
Try It Out Generate a Runtime Error
1.
Open compilationerror.aspx in Web Matrix, go to the All Window, and make the following
change to the case of the
if statement:
public void CompleteOrder(Object sender, EventArgs e)
{
if (txtQuantity.Text == "")
{
lblOrderConfirm.Text = "Please provide an Order Quantity.";
}
else if (Convert.ToInt32(txtQuantity.Text) <= 0)
{
lblOrderConfirm.Text = "Please provide a Quantity greater than 0.";
}
else if (Convert.ToInt32(txtQuantity.Text) > 0)
{
lblOrderConfirm.Text = "Order Successfully placed.";
}
}
2. Save the file as runtimeError.aspx.

3. View the runtimeError.aspx file using the browser. Provide a non-numeric value, such as
ABC, to the order quantity textbox, and click the Complete Order button. Figure 14-4 shows the
result:
519
Debugging and Error Handling
Figure 14-4
How It Works
Our control block validates input for null values, and for numeric values that are equal to or less than
zero. It does not check input for other non-numeric input values. The code generated a runtime error
when the
ConvertTo.Int32() function tried to convert a non-numeric entry to an integer field. The
process of checking for this type of errors is called validation. To validate the data entry values, your
control block should have an extra couple of lines as follows:
else if (Convert.ToInt32(txtQuantity.Text) <= 0)
{
lblOrderConfirm.Text = "Please provide a Quantity greater than 0.";
}
Let's take a closer look at validating user input.
Trapping Invalid Data
Testing your code by supplying both legal and illegal values is crucial for the proper functioning of your
program. Your program should return expected results when providing legal values, and handle errors
when supplied with illegal values. In this section, we'll talk about ways to handle the illegal values
supplied to your program. We have two objectives here:
520
Chapter 14
❑ Prevent the occurrence of errors that may leave you with many disgruntled users
❑ Prevent your program from accepting and using illegal values
There are two main techniques used to fulfill these objectives: manual trapping and using validation
controls.
Manual Trapping

When building the application, you could create error traps to catch illegal values before they get into the
page execution, where they might halt the execution of the page or provide invalid results. How do you
block illegal values from sneaking into page processing? Let's develop a page that accepts order quantity
from the user.
Try It Out Catching Illegal Values
1.
Open runtimeError.aspx in Web Matrix and make the following changes in the All Window:
<%@ Page Language="c#" Debug="true" %>
<script Language="c#" runat="server">
void CompleteOrder(object sender, EventArgs e)
{
if (txtQuantity.Text!= "")
{
if (!(Char.IsNumber(txtQuantity.Text,0)))
{
if (txtQuantity.Text.Substring(0,1)!= "-")
{
lblOrderConfirm.Text =
"Please provide only numbers in Quantity field.";
}
else
{
lblOrderConfirm.Text =
"Please provide a Quantity greater than 0.";
}
}
else if (Convert.ToInt32(txtQuantity.Text) == 0)
{
lblOrderConfirm.Text = "Please provide a Quantity greater than 0.";
}

else if (Convert.ToInt32(txtQuantity.Text) > 0)
{
lblOrderConfirm.Text = "Order Successfully placed.";
}
}
else
{
lblOrderConfirm.Text = "Please provide an Order Quantity.";
}
}
</script>
<html>
<head>
<title>Manual Trapping Example</title>
</head>
521
Debugging and Error Handling
2. Save the file as manualtrapping.aspx.
3. Load this file using your browser. Figure 14-5 shows the result of providing an order quantity of
10:
Figure 14-5
4. Supply different values to the order quantity textbox and check whether the page behaves as
expected.
How It Works
Notice that we have added an extra directive to the page calls:
<%@ Page language="C#" Debug="true" %>
This will enable us to view detailed error messages throughout the course of the chapter. How this
works will become clearer as we progress.
We are using two
Label controls: a TextBox control and a Button control. The first Label control is the

label for the order quantity textbox:
<asp:Label text="Order Quantity" runat="server" />
The second label control called lblOrderConfirm is used to display a message after processing the
order, indicating whether the order was successfully placed or not:
<asp:Label id="lblOrderConfirm" runat="server"/>
The textbox accepts an entry from the user – the order quantity:
<asp:TextBox id="txtQuantity" runat="server" />
The button calls the CompleteOrder() function when clicked:
<asp:Button id="btnComplete_Order" Text="Complete Order"
onclick="CompleteOrder"
522
Chapter 14
runat="server"/>
Within the CompleteOrder() function, we create a series of checks to avoid illegal values. First, we
check for 'no entry' to the textbox:
if (txtQuantity.Text!= "")
{

}
else
{
lblOrderConfirm.Text = "Please provide an Order Quantity.";
}
This is followed by the numeric check and checks to ensure that the quantity is greater than zero:
if (!(Char.IsNumber(txtQuantity.Text,0)))
{
if (txtQuantity.Text.Substring(0,1)!= "-")
{
lblOrderConfirm.Text =
"Please provide only numbers in Quantity field.";

}
else
{
lblOrderConfirm.Text =
"Please provide a Quantity greater than 0.";
}
}
else if (Convert.ToInt32(txtQuantity.Text) == 0)
{
lblOrderConfirm.Text = "Please provide a Quantity greater than 0.";
}
Finally, the code for accepting the order:
else if (Convert.ToInt32(txtQuantity.Text) > 0)
{
lblOrderConfirm.Text = "Order Successfully placed.";
}
}
Using Validation Controls
The second technique is to use one or more of several validation controls provided by ASP.NET (refer to
Chapter 10 for a detailed discussion on validation controls.)
Validation controls are used to validate user input. For instance, you could use the
RequiredFieldValidator control to ensure that users enter a value to a textbox. By doing this, you
could avoid runtime errors that occur because of your program using a null (unknown value), when it is
expecting an ’entry’ from the user.
523
Debugging and Error Handling
By using one of the many validation controls provided by ASP.NET, you could present the users with a
message informing them about the incorrect value supplied, and the value your program is expecting.
This prevents the program from processing an illegal value and developing an error.
Let's look at an example to demonstrate how to use these controls. We'll use the

RequiredFieldValidator to ensure that the user provides a value for the Order Quantity field.
Try It Out Using RequiredFieldValidator
1.
Open manualtrapping.aspx (from the previous exercise) in Web Matrix, and make the
following changes in the
All Window:
<form method="post" action="usingvalidationcontrol.aspx" runat="server">
<asp:Label text="Order Quantity" runat="server" />
<asp:TextBox id="txtQuantity" runat="server" />
<asp:RequiredFieldValidator ControlToValidate="txtQuantity" runat="server"
ErrorMessage="Please enter a value in the Order Quantity Field">
</asp:RequiredFieldValidator>
<br />
<asp:Button id="btnComplete_Order" Text="Complete Order"_
onclick="CompleteOrder" runat="server"/>
<br>
<asp:Label id="lblOrderConfirm" runat="server"/>
</form>
2. Save this file as usingvalidationcontrol.aspx.
3. Use your browser to open usingvalidationcontrol.aspx. If you try to complete the order
without entering anything, you're presented with the request that you see in Figure 14-6:
Figure 14-6
How It Works
In this example, we have used a RequiredFieldValidator control. The ControlToValidate
property is used to specify the control that we are validating:
<asp:RequiredFieldValidator ControlToValidate="txtQuantity" runat="server"
524
Chapter 14
In this case, we are validating the order quantity textbox. The ErrorMessage property is used to
provide an error message when the user does not enter a value to the order quantity field.

ErrorMessage="Please enter a value in the Order Quantity Field">
The validation control saves us the extra second guessing of typical mistakes a user might make.
System Errors
These errors are generated by ASP.NET itself. They may be due to malfunctioning code, a bug in
ASP.NET, or even one in the CLR. Although you could find this type of error, rectifying it is usually not
possible – particularly if it is an ASP.NET or CLR error.
Other errors that can be placed in this category are those that arise due to the failure of a Web server or
component, a hardware failure, or a lack of server memory.
When an error occurs in an ASP.NET page, the error details are sent to the client. However, ASP.NET by
default shows detailed error information only to a local client.
A local client is a browser running on the same machine as the Web server and therefore only viewable
by the site administrator. For instance, if you create the ASP.NET examples in this book on a machine
running a Web server, and access them using a browser on the same machine (as you would do with
Web Matrix), then the browser is a local client. If this was deployed on a network using IIS, you might
see the error, but other users on the network would just receive a generic "something's wrong" kind of
message.
So, the fact that ASP.NET sends detailed information about errors to local clients is actually very helpful
to the developer during the development phase.
Finding Errors
Having adopted the good coding practices and different techniques to trap invalid data in our programs,
why are we still talking about finding errors? Even after taking precautions, our program might still end
up with an error page. It could be because we did not cover all possible error scenarios in our testing
(point the fingers at the testers), or another program did not behave as expected (refer it to the other
team) or worse, the server administrators did not set up the server right (blame it on the network
administrators).
However well you plan, it is difficult, if not impossible, to catch every bug in advance. So, what do we
do if our well-constructed code still doesn't work? We will discuss this topic next.
Let's go back to the local client scenario. ASP.NET displays a call-stack when a runtime error occurs. A
call-stack contains a series of function calls that lead up to an error. Before you do this, delete (or
rename) any

web.config files residing with your samples; otherwise all errors generated will be
handled by this file.
Let's create a page that causes a runtime error.
525
Debugging and Error Handling
Try It Out Viewing the Call-Stack
1.
Open Web Matrix and create a file called callStack.aspx. Then type the following code into
the
All Window:
<%@ Page Language="c#" Debug="true" %>
<script language="c#" runat="server">
void CreateRunTimeError()
{
int[] array = new int[5];
int arrayIndex = 5;
array[arrayIndex] = 5;
Response.Write("This should never be reached");
}
</script>
<%
CreateRunTimeError();
%>
2. Save the file and open it in your browser. You should see something like Figure 14-7 (as long
you haven't got a
web.config file in the same folder as the .aspx file):
Figure 14-7
526
Chapter 14
How It Works

In the block of code we entered, we set up an array of five elements, numbered from 0 to 4, and tried to
access an element with the number 5, which is an element beyond the end of the array:
int[] array = new int[5];
int arrayIndex = 5;
array[arrayIndex] = 5;
On running this code, an error was generated when the program tried to execute an integer data type
containing a string. We were presented with the error page above. The error page contains different
sections, such as
Exception Details (we'll discuss exceptions shortly), Source Error, Stack Trace,
and so on. The
Stack Trace contains the call-stack that says that the value we are trying to assign to an
integer variable is not valid. If you look through the call-stack, you can see the series of functions that
led to the exception.
The information provided under the
Source Error section is useful in locating the line in which the
error occurred. The display of this information is controlled by the
Debug mode.
Debug Mode
If Debug mode is enabled, the Source Error section of the error message is displayed as part of the error
message that pinpoints the location in the code that generated the error. If
Debug mode is disabled, the
Source Error section is not displayed.
Now the question is: where and how can we set the value for
Debug mode?
It can be set in two different places. The first place should be familiar as we have used it twice already
within this chapter. You can set it at every page within the
Page directive at the top of the page, as
shown below:
<%@ Page Debug="true" %>
To disable it, you can set it to false:

<%@ Page Debug="false" %>
If the Debug mode is set like this (at the page level), the setting is applied only to that specific page.
Let's return to our previous example, and disable the
Debug mode at the page level:
Try It Out Disable the Debug Mode
1. Open the callstack.aspx file in Web Matrix, and in the All window, insert the following line
at the top of the page – don't replace the existing declaration:
<%@ Page Language="C#" Debug="false" %>
527
Debugging and Error Handling
2. Save the file as debugmode.aspx and access the page using the browser. You will see an error
page as shown in Figure 14-8:
Figure 14-8
How It Works
We disabled the Debug mode in our debugmode.aspx by adding the following line at the top of the
page:
<%@ Page Debug="false" %>
On running our new file in the browser, we saw a new error message. Under the Source Error section,
there are instructions to enable the
Debug mode for displaying the source code that generated the
exception, but the actual source code is not there.
As mentioned a moment ago, there are two ways to set the Debug mode. The second way is to set it at
the application level, using the
<compilation> configuration section in the configuration file (see Chapter
15).
528
Chapter 14
Setting the Debug mode at the application level will display the Source Error section in the error message
for all the files under the application. This has a performance overhead though, so before moving your
application to a production environment, make sure you disable the

Debug mode.
Tracing
When developing an application, we execute the page at different levels of development, and for
effective debugging, we always need to see the values assigned to variables and the state of different
conditional constructs at different stages of execution. In ASP, developers used the ubiquitous
Response.Write statement to display this information. The downside of this is that while completing
the application development, the developer had to go to every page and either comment or remove the
Response.Write statements they created for testing purposes. ASP.NET provides a new feature to
bypass all of this. It is the
Trace capability.
The Trace feature provides a range of information about the page, including request time, performance
data, server variables, and most importantly, any message added by the developers. It is disabled by
default. Like the
debug mode, tracing can be either enabled or disabled at either the page (or the
application) level. We'll now consider these levels in more detail.
Page-Level Tracing
Tracing can be enabled at the page level to display trace information using the Page directive's Trace
attribute, as shown below:
<%@ Page Trace = "true" %>
Tracing can be disabled using:
<%@ Page Trace = "false" %>
When tracing is enabled, the trace information is displayed underneath the page's contents. Let's create a
simple ASP.NET page with a
TextBox and a Label control, and enable tracing at the page level.
Try It Out Enabling Trace at the Page Level
1.
Open Web Matrix, create a page called pageleveltracing.aspx, and type in the following
code to the
All Window:
<%@ Page Trace="true"%>

<html>
<head>
<title>Page Level Tracing</title>
</head>
<body>
<form method="post" action="pageleveltracing.aspx" runat="server">
<asp:label text="Name" runat="server" />
<asp:textbox name="txtName" runat="server" />
</form>
</body>
</html>
529
Debugging and Error Handling
2. Save this file and view it using the browser as shown in Figure 14-9:
Figure 14-9
How It Works
First, we enabled the page trace with the line:
<%@ Page Trace="true"%>
We then created a textbox with some text beside it. What we got was the textbox plus a whole load of
tracing. Let's look at each section of the trace output to get a fuller understanding of what they display:

Request Details: This section contains information pertaining to the page request, such as the
Session ID for the current session, the request type (whether it is GET or POST), the time at
which the request was made, the encoding type of the request among others, as shown in Figure
14-10:
Figure 14-10
530
Chapter 14
❑ Trace Information: This is the section in which the actual trace information is displayed along
with the messages written by developers. As shown in Figure 14-11, this section displays the

category, the message, the time since the first message, and the most recent message displayed:
Figure 14-11

Control Tree: This section displays details about the different controls used in the page. The
details include the ID provided for the control, the type of control used, and its position among
other controls, as shown in Figure 14-12:
Figure 14-12

Cookies Collection: This section displays all cookies used in the page. Figure 14-13 shows only
the
SessionID because it is the only member of the cookies collection used in our page:
Figure 14-13

Headers Collection: As shown in Figure 14-14, this section displays the various HTTP headers
sent by the client to the server, along with the request:
Figure 14-14
531
Debugging and Error Handling
❑ Server Variables: This section displays all the members of the Server Variables collection as
shown in Figure 14-15:
Figure 14-15
Now that we've introduced the information displayed in the trace page, let's talk about techniques used
to write a message to the
Trace Information section, and get updates on what goes on behind the scenes as
your code is executed.
Writing to the Trace Log
Each ASP.NET page provides a Trace object that can be used to write messages to the trace log. You can
use two methods to write messages to the trace log:

Trace.Write()

❑ Trace.Warn()
The messages are only displayed when tracing is enabled.
Both methods are used to write messages to the trace log, but when using the
Trace.Warn() method,
the messages are displayed in red. You may want to use
Trace.Warn() for writing (and highlighting)
unexpected results or incorrect values for variables in your program. Let's create an example that shows
how to use these methods.
Try It Out Writing to the Trace Log
1.
Open Web Matrix, create a file called writetotrace.aspx, and type the following code into All
Window:
532
Chapter 14
<%@ Page Trace="true"%>
<script Language="c#" runat="server">
void WriteToTrace()
{
// This is where messages are written to Trace Log
// Syntax as follows:
// Trace.Write ["Category", "Message to be displayed"];
// Trace.Warn ["Category", "Message to be displayed"];
int intCounter=1;
Trace.Write("FirstCategory", "Variable is initialized");
while (intCounter > 10)
{
intCounter++;
}
if(intCounter < 10)
{

Trace.Warn("ErrorCategory", "Value of intCounter is not incrementing");
}
}
</script>
<%
WriteToTrace();
%>
2. Save this file and open it in your browser. The message we wrote using the Trace.Warn()
method is shown in Figure 14-16. It's the ErrorCategory line and is displayed in red:
Figure 14-16
533
Debugging and Error Handling
How It Works
The first thing we do is declare intCounter (which we're using as a label) as an integer data type, and
assign a value of
1 to it:
int intCounter=1;
We write a message to the trace log, which says our variable has been initialized:
Trace.Write ("FirstCategory", "Variable is initialized");
The next three lines of code constitute a loop, so that while intCounter is greater than 10, it will be
incremented:
while (intCounter > 10)
{
intCounter++;
}
This looks like a programming error. As we initialized intCounter to 1, it cannot be greater than 10. We
then introduce our
Trace.Warn() statement that displays a warning message if intCounter is less
than
10 (which it is). This is what we want because, in order for the loop to work, intCounter must be

greater than
10:
if(intCounter < 10)
{
Trace.Warn("ErrorCategory","Value of intCounter is not incrementing");
}
Note that we've specified category information in both, Trace.Write() and Trace.Warn(), methods.
Application-Level Tracing
As stated earlier, tracing can also be enabled or disabled at the application level, in which case the
tracing information is processed for all the pages under the application.
A page-level trace setting always overrides the application-level trace setting. For instance, if tracing is
enabled at the application level but disabled for a page, then the tracing information will not be
displayed for that page.
Application-level tracing is set using the
<trace> section in the configuration file (web.config)
discussed earlier. The following is an example of the
<trace> section:
<configuration>
<system.web>
<trace enabled="true" requestLimit="10" pageOutput="true"
traceMode="SortByTime" localOnly="true" />
</system.web>
</configuration>
The use of tracing in web.config is discussed in more detail in Chapter 15.
534
Chapter 14
Trace.axd: The Trace Information Log
When application-level tracing is enabled (there has to be a web.config file present for this – you can
copy the previous code and save it as
web.config just to test it), the trace information is logged to the

rrace.axd file. This file can be accessed using the URL for your application, followed by trace.axd –
for example,
http://yourwebservername/applicationname/trace.axd
Figure 14-17 shows how the trace.axd file looks in the browser, after another browser has made a
request to
manualtrapping.aspx and received a response from the server:
Figure 14-17
trace.axd provides a summary of each page requested, and a View Details hyperlink takes you to the
trace information page for that particular screen.
Handling Errors
We've seen the kind of errors that can occur, how to avoid them, and how to find them if things do go
wrong. But what if the errors just won't go away; annoyingly, this happens all the time! Don't worry
though, because there is a way of dealing with this – we can use an error handling technique to catch
them. Even though we can't write a 'magical' program to fix all the bugs on the fly, we can let users
know that there is a bug and not to worry if things don't look right. In this section, we will talk about
different error handling techniques that can be used to catch errors.
On Error Goto?
If you have a background in Visual Basic, you might be asking yourself whether you can use syntax like
On Error Resume Next in C#, and the short answer is, no you cannot! C#'s built-in error handling syntax
is based on structured exception handling. Structured exception handling in C# does not allow you to
simply skip the line of code producing the error and proceed with the next one. Such a function is OK
for a script-based application such as a traditional ASP page, but for the object-oriented world of C# and
ASP.NET, you need something more robust. Structured exception handling also largely replaces the
535
Debugging and Error Handling
crude error handling offered by On Error Goto Label syntax as well. C# also does not have any
equivalent to the Visual Basic
Err object.
Structured Error Handling
We have already come across structured exception handling in this book wherever we have actually

needed it:
❑ We used it to deal with situations where conversion between data types might fail and generate
a run-time error.
❑ We mentioned it as a means of dealing with situations where conversion between object types
might fail and generate a runtime error.
❑ We used it when dealing with databases. Runtime errors can occur for many reasons including
the unavailability of the database, trying to access a non-existent data field, or trying to update a
read-only data field.
In all cases, we referred to this point in the book where we look closely at implementing error handling.
However, to provide a complete picture of what C# error handling can achieve, we are going right back
to the basics.
So what do we mean by structured error handling? Pretty much just that: handling errors via a
particular structure. Lines of code are grouped together, and different handlers are provided to handle
different errors within those groups. The following list shows the sequence of events that take place
when using structured error handling:
1. We execute one or more lines of code in a group. They might execute without an error, or they
might generate one or many different kinds of errors.
2. If errors are generated, a handler (which you will have defined) corresponding to the error will
be called. If there is no error, no handler will be called.
Two important things need to be done for effectively using structured error handling:
❑ Creating a group of lines or a block of code.
❑ Creating handlers for the different kinds of errors that could occur when the code block is
executed.
Before launching into this subject, we need to introduce the concept of exceptions.
Exceptions
An exception is any error condition or unexpected behavior that occurs during the execution of a
program, and consequently disrupts the normal flow of execution – in fact, the term is just shorthand
for exceptional event. If an error occurs within a method call, the method creates an exception object and
You can also define a generic handler that handles any errors for which you did not
define a specific handler.

536
Chapter 14

×