Working with Custom Error Pages Using ASP.NET
 
Published: 12 Sep 2006
Abstract
In this article Sanjit examines the creation of custom error pages in ASP.NET using C#.
by SANJIT SIL
Feedback
Average Rating: 
Views (Total / Last 10 Days): 65901/ 234

Introduction

Every application should have error handling.  We try to trap errors using try-catch-finally block.  But what happens in the case of an unhandled exception in application?  ASP.NET produces an error page (usually located at c:\winnt\help\iishelp\common) when an application throws an unhandled exception or when we deploy an .aspx file whose source contains a syntax error without compiling it inside Visual Studio .NET first.  By default, ASP.NET displays error messages that include .NET error description along with a stack trace (see Figure 1).  There is a lot of information in the error message.  The stack trace points out the location where the specific error occurred and the last line informs us about the version used in .NET Framework.  This information is very useful for a developer because it tells why and where the error occurred.  

On the other hand, it may confuse the general user as he or she will not understand anything by seeing the displayed error message.  As a result, it may create a bad opinion in his or her mind and even may be the reason for loss of business.  Even hackers use the information displayed in the error message with a bad intention in mind as the line of code might contain confidential information, such as the password to access a database.   We do not want this page be visible to the site's visitors and we should redirect the browser to a custom error page on which we can instruct users about error causes and possible remedies.  ASP.NET provides several levels at which we can handle and respond to errors that may occur when we run an ASP.NET application.  This article will also provide some code which can be used to create custom error pages for ASP.NET web applications.  Although this article describes how to provide custom error pages and general error reporting, it is not going to describe error handling using try-catch-finally block.  The sample code snippets in this article have been written in C#.

Solution

ASP.NET provides three main methods that allow us to trap and respond to errors when they occur.

Page_Error of .aspx file or associated codebehind

Application_Error in Global.ascx file

CustomErrors section of the application configuration files (Web.config)

Sequence of Events

The actual order of error handling events is as follows.

Page_Error of .aspx file or associated codebehind

Application_Error in Global.ascx file

CustomErrors section of the application configuration files (Web.config)

Server.ClearError and Server.GetLastError

Two important server side methods named Server.ClearError and Server.GetLastError are used in the following code listing.  Here is a brief description of these two methods.

Server.ClearError: Use this method to handle the exception and stop the error to trigger the subsequent error event or display the error to the user.  If we do not clear the exception by using the Server.ClearError, the unhandled exception will continue to propagate up to the Application_Error event.  If we use Server.ClearError to clear the exception in Application_Error, the default redirect setting in the Web.config file will not redirect the user because the unhandled exception no longer exists.  If you want the default redirect setting to properly redirect users, do not clear the exception in Application_Error.

Server.GetLastError: A call to Server.GetLastError will return the most recent error.

Page_Error Method

ASP.NET provides as the 1st level of error handling by means of Page_Error event handler which provides a way to trap errors that occur at the page level in a web application.  The following example throws a divide by zero exception which forces an error to occur in the Page_Load event handler.  To demonstrate Page_Error event handler we have to create or add a new web form (say) named as PageError.aspx and then we should add the following code to PageError.aspx.

Listing 1

<script language=C# runat="server">
void Page_Load(object sender, System.EventArgs e)
{
      int i=0;
      int j=5;
      int k=0;
      k=j/k;
}
 
public void Page_Error(object sender,EventArgs e)
{
      Exception objError = Server.GetLastError().GetBaseException();
      string strError = "<b>Error Has Been Caught in Page_Error event</b><hr><br>" + 
                  "<br><b>Error in: </b>" + Request.Url.ToString() +
                  "<br><b>Error Message: </b>" + objError.Message.ToString()+
                  "<br><b>Stack Trace:</b><br>" + 
                        objError.StackTrace.ToString();
      Response.Write(strError.ToString());
      Server.ClearError();
}
</script> 

AutoEventWireup

The AutoEventWireup attribute may have a value of true or false.  When an ASP.NET Web Application is created by using Microsoft Visual Studio .NET, the value of the AutoEventWireup attribute is set as false.  In this code sample the AutoEventWireup attribute is not explicitly set.  If you do not explicitly assign a value to the AutoEventWireup attribute, the default value true is used.  There is an important difference between the default value that ASP.NET uses and the default value that the Visual Studio .NET template code assigns to this attribute.  If the AutoEventWireup attribute value is set to false, the event handlers that are declared in the .ASPX page do not fire.  To test the same you can write AutoEventWireup=”false” and then you will see that a white page is coming without showing the content of Figure1. 

Listing 2

<%@ Page language="c#"
 Codebehind="PageError.aspx.cs" AutoEventWireup="false"
 Inherits="CustomError.PageError" %>

After saving the page, when we run the application we will see that the error is thrown and reported according to the code specifications.  The following screen shot (see Figure 1) describes the error handled by the Page_Error event handler.

Figure 1


Application Error Method

Along with page level error handlers, ASP.NET gives developers the ability to provide application-level error handling.  The page-level error handling comes first, after ASP.NET calls the Page_Error procedure, and then ASP.NET calls the Application_Error procedure.  We can simply display error information, log the event to the Windows Event Log, send E-mail to system administrator or we can simply redirect to another page.

The Application_Error event handler is specified in the Global.asax file of our application.

Here a new page named ApplicationError.aspx is added and the following code is written in that page to generate the error.

Listing 3

<script language=C# runat="server">
  void Page_Load(object sender, System.EventArgs e)
  {
    int i=0;
    int j=5;
    int k=0;
    k=j/k;
  }
</script>

The AutoEventWireup attribute as discussed in the "Page_Error" section also applies to the code sample in this step.  To trap the error generated in the page load of ApplicationError.aspx using the above code listing we have to add the following code to the Global.asax file.

Add the following namespace to use the event log.

Listing 4

using System.Diagnostics;

Add the following code in Application_Error event to trap the error that will be thrown in the Page_Load event handler of the ApplicationError.aspx page.

Listing 5

public void Page_Error(object sender,EventArgs e)
{
      Exception objError = Server.GetLastError().GetBaseException();
      string strError = "<b>Error Has Been Caught in Page_Error event</b><hr><br>" + 
                  "<br><b>Error in: </b>" + Request.Url.ToString() +
                  "<br><b>Error Message: </b>" + objError.Message.ToString()+
                  "<br><b>Stack Trace:</b><br>" + 
                        objError.StackTrace.ToString();
      Response.Write(strError.ToString());
      Server.ClearError();
}
</script> 

If we right-click the page and then click View in the Browser, the page will be blank (i.e. white screen).  However, we should notice that a new entry has been added in the event log.  This sample makes an entry in the Application log which is accessible from the Event Viewer.

In this function we can even save error information to session state and then perform the redirect manually.

Listing 6

protected void Application_Error(Object sender, EventArgs e)
{
  Exception objError = Server.GetLastError().GetBaseException();
  string strError = "Error Has Been Caught in Application_Error event\n" +
    "Error in: " + Request.Url.ToString() + "\nError Message:" +
    objError.Message.ToString() + "\nStack Trace:" +
    objError.StackTrace.ToString();
  Session["error"= strError.ToString();
  Server.Transfer("WebForm1.aspx");
 
}

Now, on the custom error page we will have access to all the information pertaining to the error.  We can then use this for error reporting via email to the developers/system admin or to display a more pleasing error message.

Understanding Web.config File

<customErrors> section is responsible for handling the error on the basis of the setting made in that section if we do not call Server.ClearError, trap the error in the Page_Error or Application_Error event handler.  In the <customErrors> section we can specify a redirect page as a default error page (defaultRedirect) or specify to a particular page based on the HTTP error code that is raised.  We can use this method to customize the error message that the user receives.
If an error occurs that is not trapped at any of the previous levels in the application (i.e. either in page level or in application level), this custom page is displayed.

In the following code, Server.ClearError() ; is commented in the Application_Error event of  the Global.asax file so that Server.ClearError is never called.  This means the error will be handled on the basis of the setting made in <customErrors> section in the Web.config file.

Listing 7

using System.Diagnostics;
protected void Application_Error(object sender, EventArgs e)
{
  Exception objError = Server.GetLastError().GetBaseException();
  string strError = "Error Has Been Caught in Application_Error event\n" +
    "Error in: " + Request.Url.ToString() + "\nError Message:" +
    objError.Message.ToString() + "\nStack Trace:" +
    objError.StackTrace.ToString();
  EventLog.WriteEntry("CustomError", strError, EventLogEntryType.Error);
//Server.ClearError();
}     

Add the following code to the <customErrors> section to redirect the user to a custom page.

Listing 8

<customErrors defaultRedirect="http://hostName/applicationName/CustomError.htm" mode="On">
</customErrors>

We should modify the file path in defaultRedirect attribute so that it references the relevant Web server and application names.

Because the errors that are trapped at this level are sent to a default error page, you must create an error page named CustomError.htm.  Keep in mind that you are using this method to control what is presented to the user, so this example uses an .htm page for the error page.  Add the following code to CustomError.htm.

Listing 9

<HTML>
<HEAD>Custom Error Page</HEAD>
<BODY>
<H1><FONT COLOR=RED>There is a problem in site. Please try again later. </FONT> </H1>
</BODY><HTML>

It should be noted that a custom error page may be a simple HTML file or an ASPX file; it depends upon requirements.

If we run ApplicationError.aspx in the browser, we will see that when the error is thrown we are redirected to the CustomError.htm page.

In the above code listing the <customErrors> section includes a mode attribute that is set to On. The mode attribute is used to control how the error redirection occurs.  For example, if anyone is developing the application, he or she most likely wants to see the actual ASP.NET error messages and does not want to be redirected to the more user-friendly error page.  The mode attribute includes the following settings or options.

On: This option specifies that custom errors are enabled.  If no defaultRedirect is specified, users see a generic error.

Off: This option specifies that custom errors are disabled.  This allows the display of detailed errors.

RemoteOnly: This option specifies that custom errors are shown only to remote clients and ASP.NET errors are shown to the local host.  This is the default.

Note that defaultRedirect optional attribute specifies the default URL to direct a browser if an error occurs.  When defaultRedirect is not specified, a generic error is displayed instead.  The URL may be absolute (for instance, http://localhost/CustomErrorPage.htm) or it may be relative.  A relative URL such as /CustomErrorPage.htm is relative to the Web.config file that specified the defaultRedirect URL and not to the Web page in which the error occurred.

Handling specific errors

The customErrors section of the web.config file allows us to handle individual errors differently. Errors are distinguished by their HTTP error codes; we can also specify a particular page to redirect to that is based on the HTTP error code that is raised.

The followings are some of the most common errors.

400: Bad Request - This means the request could not be understood by the server.  The request                                                   

        was denied due to a syntax error in the request.

401:  Unauthorized - This means the request requires authentication.

402: Payment required - This means the data is not accessible at the time.  The owner of the    

       space has not yet paid his or her service provider or the server was unable to serve the data

       that was requested.

403: Forbidden - This means the IP address or the username/password entered were not correct  

       and the request was denied as there was no permission to access the data.

404: Not found - This means the document requested either no longer exists or has            

       never existed on the server.

405: Method not allowed- Means the method you are using to access the document is not

       allowed.

408: Request Timeout - Means the server has closed the socket due to communications

        between the client and server taking too long.

414: The URL requested is too long.

500: Internal server error. The server encountered an error - This is most often caused by a

        scripting problem, a failed database access attempt, or similar reasons.

503: Service unavailable- This means the server is overloaded or down for maintenance and was

       unable to process the client request.

A complete HTTP status code listing is available online.  We may expand the customErrors section of the web.config file to handle specific error codes.  We can achieve the expansion by adding error elements under the customErrors element.  The following sample shows how we may accomplish this.

Listing 10

<customErrors mode="RemoteOnly" defaultRedirect="CustomErrorPage.aspx">
<error statusCode="400" redirect="ErrorPage400.aspx" />
<error statusCode="401" redirect="ErrorPage401.aspx" />
<error statusCode="402" redirect="ErrorPage402.aspx" />
<error statusCode="403" redirect="ErrorPage403.aspx" />
<error statusCode="404" redirect="ErrorPage404.aspx" />
<error statusCode="408" redirect="ErrorPage408.aspx" />
<error statusCode="414" redirect="ErrorPage414.aspx" />
<error statusCode="500" redirect="ErrorPage500.aspx" />
<error statusCode="503" redirect="ErrorPage503.aspx" />
</customErrors>

The above sample handles each specific error with the corresponding page.  The statusCode attribute of the error element designates the error and the redirect attribute defines the page to use.  This allows us to customize the error message based upon the error encountered.  The default error page handles any error that is not specified.

References

Conclusion

This article provides a detailed overview of ASP.NET custom error pages and several different methods to implement them.  When an error will occur, end users should always have a view of meaningful and friendly error pages.  At the same time, it is also important that people on the other end (the administrator or developers) are alerted about problems.  Using the Custom Error Page we can also provide the page with the site’s look and feel.  Custom error page design becomes a normal part of site design.



User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-03-09 4:36:47 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search