Dot Net Perls

Custom Error Pages Tutorial in ASP.NET

by Sam Allen - Updated April 29, 2009
ASP.NET default error page

Problem. You want to specify a custom page as your error page in your ASP.NET website. This allows you to show visitors a link to your home page or to your sitemap. Solution. We will use the customErrors element in your Web.config to gain specialized errors the easiest way.

1. Opening Web.config

On the right side of Visual Studio, you will see the Web.config file icon. Open it and add the highlighted markup to your project in the appropriate location. Note that new Web.configs have the customErrors element already.

<?xml version="1.0"?>

<configuration>
    <appSettings/>
    <connectionStrings/>
    <system.web>

        <customErrors defaultRedirect="404.aspx" mode="On" />

    </system.web>

</configuration>

Description of the XML document. Every new Web.config contains a comment that tells you what customErrors is used for. Here's what it says:

The customErrors section enables configuration of what to do if/when
an unhandled error occurs during the execution of a request.

Specifically, it enables developers to configure html error pages to
be displayed in place of a error stack trace.

2. Making your 404 file

You can use any file as a 404 error file in the defaultRedirect attribute value, but I suggest you use a new web form file called 404.aspx, or a generic handler called 404.ashx.

Getting started with ASPX page. Click on Add Existing Item... in the Website menu and add a Web Forms page called 404.aspx. You don't to check the code-behind option.

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Error</title>
</head>
<body>

    <p>Sorry, the page could not be found.
    <br/>
    [<a href="Sitemap.aspx">Sitemap</a>]</p>

</body>
</html>

Description. The markup above can be placed in the 404.aspx file directly. Note that you will want to have your site-specific text and styling applied to the page. The example has a link pointing to a Sitemap.aspx file, but you will need to manually create this in your site if you want it.

3. Testing your customErrors setup

Now, click the green arrow in Visual Studio to run your project. Type an invalid URL into your browser, such as "Invalid.aspx". You should see the custom error ASPX file, 404.aspx. The remainder of this article talks about more specific options with customErrors and HTTP errors in general.

4. Important attributes for customErrors

Looking at MSDN, we can see several important attributes of customErrors. Not only that, but we can look at other sites and see a new attribute added in .NET 3.5, redirectMode. [customErrors Element (ASP.NET Settings Schema) - MSDN]

customErrors attributeIts usage
defaultRedirectThis is the simplest attribute to use for customErrors to work. In the attribute value, type in the absolute or relative URL of your error page. I used "404.aspx".
modeThis is the switch that turns the custom errors on or off. Additionally, you can specify RemoteOnly, which I recommend for projects still in active development.
Child Element: errorIf you need very specific error messages to appear, you can specify the error codes and what URLs they map to. You might have custom errors for 401 Unauthorized, 403 Forbidden, and 404 Not Found.
redirectModeYou can specify URL rewriting, which preserves the original URL in the browser. This prevents an HTTP request. [What are the hidden features of ASP.NET? - weblogs.asp.net]

5. Using StatusCode in your 404.aspx file

In the Page_Load method in your 404 page, you can assign the status code using Response.StatusCode = 404. This allows you to modify the error code to anything you want.

Background on HTTP error codes. For completeness, here are some of the most important HTTP error codes your server may produce, as well as some that are very rare in the wild. [HTTP/1.1: Status Code Definitions - www.w3.org]

Status codeIts usage
400 Bad Request
401 Unauthorized
Not often used.
403 ForbiddenThe server refuses to recognize the request, even though it is a valid request. Not useful because 404 can be used instead, which also improves security by not revealing anything.
404 Not FoundThis status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfied
417 Expectation Failed
Not often used.
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service unavailable
This occurred to me when I wrote a really popular article. I don't think testing for this error is ever useful because if your server is overloaded, error pages won't help the problem.
504 Gateway Timeout
505 HTTP Version Not Supported
Not very common.
Warning

6. Other options

You can use custom code in Application_Error in your Global.asax for more advanced error reporting and more features. Depending on the scale of your project, this could be appropriate.

7. Shared hosts like Go Daddy

Most shared server plans have a separate 404 error redirect function. You will need to specify your error page in that UI from your host as well. Neither setting alone may work completely, in my experience.

8. Summary

Here we saw how to use the customErrors element in Web.config. This lets you specify a custom page where people can click on a link to your sitemap or home page, increasing your page views and your user experience.

Final note on 404 pages. Most usability studies show that people will immediately leave a 404 page, ignoring all the options there. For this reason, I suggest you make a very simple one without much effort.

Dot Net Perls
ASP.NET | ASHX Handler Tutorial | Cache Examples and Overview | Global Variables Example | Page_Load Event and AJAX | QueryString Usage
C# | Dictionary StringComparer Tip | DateTime.TryParse Example | Reflection Field Example | Validate Characters in String
© 2009 Sam Allen. All rights reserved.