|
New Page 1
Custom Errors, IIS for Classic ASP and ASP.NET
Introduction
This article covers how to setup and use the Custom Errors options offered in
IIS (Internet Information Server) and ASP.NET to track 404, 500 errors. For all
types of users, a “404 webpage not found” or “500 internal server errors” are
frustrating. From the end-user experience, this could potentially have the
visitor not come back to your website. This article introduces a technique to
capture these errors to a database.
Classic ASP and ASP.NET have different ways to control the user experience when
an error occurs. Classic ASP relies on IIS “Custom Errors” section to redirect
when an error happens. ASP.NET uses settings in the <customErrors> section
contained in a web.config. This can make it difficult if your website has a
combination of HTML, ASP and ASP.NET webpages. Having different ways to
configure can be impossible sometimes if you are in a shared hosted environment.
The solution I came up with centralized all errors to a single database regardless of extension.
We will discuss how to setup, record and report on
these errors. Hopefully this will help make the end user experience more
enjoyable and keep them coming back day after day.
Webpage to process, record the error to a database.
First thing to do is develop a dynamic webpage (ASP or ASP.NET) that will
capture and record to a database. For this article, my intention isn’t to
discuss the complexity of making the error page. This could be an entire article
but for our purposes, this will capture and record to the database.
For this article, we will use the pages I used on ASPFree.com. At the time it
was easier to have separate pages for the 404, 500 errors. This could easily be
done in a single webpage. To get started, create create two files named 404.aspx, 500.aspx,
copy and paste the code and place in the root of your website.
404 webpage – 404.aspx
<%@ Page Language="VB" Trace="True" %>
<%@ Import Namespace="System.data" %>
<%@ Import Namespace="System.data.sqlclient" %>
<%@ Import Namespace="system.configuration" %>
<script language="VB" runat=server>
Sub Page_Load(Sender as Object, E as EventArgs)
If (Not Request.QueryString("aspxerrorpath") Is Nothing) Then
Dim objConn As SqlConnection = New
SqlConnection(ConfigurationSettings.AppSettings("dbConn"))
dim pg as string = Request.QueryString("aspxerrorpath").ToString()
dim cmd as SQLCommand = new SqlCommand("sp_tblNotFoundPages", objConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("@strPageLookedfor", SqlDbType.VarChar,
500))
cmd.Parameters("@strPageLookedfor").Value = pg
cmd.Parameters.Add(New SqlParameter("@strTypeOfError", SqlDbType.VarChar, 50))
cmd.Parameters("@strTypeOfError").Value = "404"
objConn.Open()
cmd.ExecuteNonQuery()
objConn.Close()
End If
End Sub
</script>
<html>
<head></head>
<body>
This page has not been found, we have record this error and notified webmaster.
</body>
</html>
500 webpage – 500.aspx
<%@ Page Language="VB" Trace="True" %>
<%@ Import Namespace="System.data" %>
<%@ Import Namespace="System.data.sqlclient" %>
<%@ Import Namespace="system.configuration" %>
<script language="VB" runat=server>
Sub Page_Load(Sender as Object, E as EventArgs)
If (Not Request.QueryString("aspxerrorpath") Is Nothing) Then
Dim objConn As SqlConnection = New
SqlConnection(ConfigurationSettings.AppSettings("dbConn"))
dim pg as string = Request.QueryString("aspxerrorpath").ToString()
dim cmd as SQLCommand = new SqlCommand("sp_tblNotFoundPages", objConn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New SqlParameter("@strPageLookedfor", SqlDbType.VarChar,
500))
cmd.Parameters("@strPageLookedfor").Value = pg
cmd.Parameters.Add(New SqlParameter("@strTypeOfError", SqlDbType.VarChar, 50))
cmd.Parameters("@strTypeOfError").Value = "500"
objConn.Open()
cmd.ExecuteNonQuery()
objConn.Close()
End If
End Sub
</script>
<html>
<head></head>
<body>
This page had an error or it’s not found. Please retry again if you feel this
was in error.
</body>
</html>
How to setup a web server to use custom Errors section
–Log into server as an Administrative user
-In IIS 6 use this path – Click Start, Program Files, Administrative Tools, and
Internet Information Services (IIS) Manager
-In IIS 5 use this path – Click Start, Program Files, Administrative Tools, and
Internet Server Manager
-Right Click on your website, chose properties
Note: This procedure needs to be done on both the 404 and 500 errors
setting.
-Select (for example 404) –
-Click Edit
-Select Message Type – URL
-In the URL field – type in /404.aspx (this can be any webpage in the root of
your website); this webpage will contains the logic to record errors to a
database.
-Click OK
-Click OK again.
How to Setup ASP.NET to capture 404 and 500 errors
Unlike HTML and ASP web-pages that rely on IIS, ASP.NET uses the <customErrors /> section in a web.config how to handle an error. There are three
potentials values, “On”, “Off” and “RemoteOnly”. These values are case sensitive
and for our article we will need the value to be “On”. To read more in-depth
about the web.config and these settings, here is an article on MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/gngrfcustomerrorssection.asp
Here is our web.config.
<configuration>
<appSettings>
<add key="dbConn" value="server=dbserver;uid=your
UID;pwd=YourPWD;Database=YourDB" />
</appSettings>
<system.web>
<customErrors defaultRedirect="/404.aspx" mode="On">
<error statusCode="404"
redirect="/404error.aspx" />
<error statusCode="500"
redirect="/500error.aspx" />
</customErrors>
</system.web>
</configuration>
Setting up the Database
The last step is setup the Database with the Tables and stored procedures that
will store the information. A side note about capturing errors, when I first
implemented this on ASPFree.com, I just captured the raw detail data. This meant
if a webpage errored 10 times in a day, there were 10 records in the database.
With over 15,000 unique documents this made for several thousand records. My
original goal was to capture the *raw* data and do a roll-up process later on.
This added a lot of complexity and made the database grow to about 500 Meg. Also
trying to roll-up a lot of records into a summary report was time-consuming and
database intensive.
I found a much simpler and more effective way. I changed the stored procedure logic
to record just a single database record for each webpage per day and then added
a column to record raw number of hits for each page. The one drawback I couldn’t
report when and what website was causing the error. For example, if a search
engine such as Google or Yahoo had a bad link indexed, I would need have to search my IIS log files to see who was sending the bad link. There was no perfect solution
without adding more logic, for my needs this technique provided more than enough information
to help keep 404 and 500 errors to a minimum.
You will need your ISP or access to SQL Enterprise manager or SQL Query Analyzer
to run the .SQL file to add the table and stored procedure.
Table
CREATE TABLE [dbo].[tblNotFoundPages] (
[Id] [int] IDENTITY (1, 1) NOT NULL ,
[pagelookedfor] [varchar] (500) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[DateofError] [datetime] NULL ,
[numOfHits] [int] NULL ,
[TypeOfError] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[tblNotFoundPages] ADD
CONSTRAINT [DF_tblNotFoundPages_numOfHits] DEFAULT (1) FOR [numOfHits],
CONSTRAINT [PK_tblNotFoundPages3] PRIMARY KEY CLUSTERED
(
[Id]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
Stored Procedure
CREATE PROCEDURE dbo.sp_tblNotFoundPages
(
@strPageLookedfor varchar(500),
@strTypeOfError varchar(50)
)
AS
Declare @chkRecord int
Declare @numOfHits int
Declare @DateOfError datetime
set @DateOfError = convert(char(10), getDate(), 101)
If exists (select Id from tblNotFoundPages where pagelookedfor = @strPagelookedfor
and DateOfError = @DateOfError)
Begin
set @numOfHits = (select numOfHits from tblNotFoundPages where pagelookedfor = @strPagelookedfor
and DateOfError=@DateOfError) + 1
UPDATE tblNotFoundPages
SET numOfHits = @numOfHits
WHERE pagelookedfor = @strPagelookedfor and DateOfError=@DateOfError
End
ELSE
INSERT INTO tblNotFoundPages(pagelookedfor, TypeOfError, DateOfError) VALUES (@strPagelookedfor,
@strTypeOfError, @DateOfError)
GO
Conclusion
We hope you find this helpful in tracking down errors on your website. I used
this solution to help track down errors on broken links, missing images or
coding errors. The most useful tool in finding errors would occur when a
“web-bot” would index ASPFree. If everything is setup correctly, you should be
able to type in a browser http://yoursite.com/PageNotFound99.asp or http://yoursite.com/PageNotFound99.aspx
and these entries will be recorded to the database.
|
|