In this article I will cover creating a custom 404 handler for your ASP.Net site.
There are tutorials out there that cover doing this, but in this article we add
an additional feature where we create a lookup table that looks up the page that
doesn't exist anymore and then redirect the request to an appropriate page related
to the missing content.
On one project I was working on, we did a massive reorganization of the company's
Web site. We consolidated several domains into one massive corporate Website. As
a result of this most of the links to pages within the site were lost. So any results
that would come up in the search engines would be broken and return a 404 error.
We didn't want to just present the browser with a generic error page, we wanted
something with some intelligence that knows what the page was they were going to
and then redirect them to an appropriate page within the new site structure.
First thing we did was to create a table to handle our lookups for the redirect.
This lookup table contained two fields, one was for the old URL string, and another
for the ID of the new page (since the new Web site is dynamically created from database
data all we need is the ID of the page).
| OldUrl |
NewTabId |
| /careers.htm |
23 |
| /aboutus.htm |
25 |
Table for URL lookup to new ID
Now that our table is created, we need to populate the table
for the lookup to handle a 404 not found error. As you can see in the table
we have old absolute path of a page, ex. "/careers.htm", which equates to a
TabID so our custom handler can lookup the page and redirect the request to
the appropriate page being generated by our application.
Option Strict On
Imports System.Data
Imports System.Configuration
Public Class _404Handler
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
Try
Dim strQuery As String = Request.ServerVariables("QUERY_STRING")
If strQuery <> "" Then
'Now we'll remove the stuff we don't need.
strQuery = strQuery.Replace("404;http://", "")
'Get rid of the domain name since we're dealing with multiple domains.
Dim intSlashPosition As Integer = strQuery.IndexOf("/")
strQuery = strQuery.Remove(0, intSlashPosition)
' now do a lookup in our table to find out if there is a related page.
Dim NewURL As Integer = DoURLLookup(strQuery)
If NewURL <> -1 Then
Response.Redirect("/DesktopDefault.aspx?TabID=" & NewURL.ToString)
Else
'if we don't have any, just send them to the home page of the site.
Response.Redirect("/")
End If
Else
Response.Redirect("/")
End If
Catch ex As Exception
Response.Redirect("/")
End Try
End Sub
'This function performs the lookup in the database to find a related page for the broken link.
Function DoURLLookup(ByVal inURL As String) As Integer
Dim cnn As New SqlConnection(ConfigurationSettings.AppSettings("connectionString").ToString)
Dim myCommand As SqlCommand = New SqlCommand("SELECT NewTabID FROM " & _
"NotFoundLookup WHERE OldURL = '" & Replace(inURL, "'", "''") & "'", cnn)
cnn.Open()
Dim result As SqlDataReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection)
If result.Read Then
Dim TabID As Integer = CType(result("NewTabID"), Integer)
cnn.Close()
Return TabID
Else
cnn.Close()
Return -1
End If
End Function
End Class
Now that we have our Web form class, all we need to do now is configure IIS to
use this page as the custom 404 error handler. To configure this page, go to Computer
Management and open the Internet Information Services node. From here, find the
Web site you want to apply the handler to. Right click on the site and select properties.
From here click on the Custom Errors tab, scroll down and find the 404 error code,
change the properties of the error handler to select URL, and then enter in the
absolute path for the handler, so for example if our 404Handler.aspx is in the root
directory, enter in "/404Handler.aspx" in this dialog.
You can also configure a 404 handler within the web.config, but in order to do
this you then need to make sure ASP.Net processes all document type requests going
to the server. By configuring the custom handler in IIS you will not need to do
this. Another option would be to create a custom HTTPModule to intercept the request
and handle accordingly, but again, this method would require that all page types
be processed by ASP.Net.
By: Patrick Santry, Microsoft MVP (ASP/ASP.NET), developer of this site, author of books on Web technologies, and member of the DotNetNuke core development team. If you're interested in the services provided by Patrick, visit his company Website at Santry.com.