404 vs 302 ASP.Net Custom Errors

Cristian Merighi () 4.50

ASP.Net achitecture sometimes lacks in sensitiveness in order to please search engines, an example to point to is the 404 errors management. In this article I try to show a search-engines-friendly way to solve this problem using HttpModules.
This article is obsolete. Some functionalities might not work anymore. Comments are disabled.

In these days I've been experiencing a conflict between the ASP.Net architecture and the rules that search engines gurus advice to follow... I introduce you to the problem:

  • Scenario: well positioned - in terms of search engines - website needs to change domain.
  • Goal: we have to try as hard as we can to mantain pages' rankings gained among the various search engines.
  • Remarks: all the pages are .aspx web forms.

We got informed that the search engines - let's say Google ...ok? - prefers to get a 404 response and some extra information about a possible alternative link...

Here's the ASP.Net vs Search Engines idiosyncrasy! If you handle the 404 exception the "usual way" (using customErrors section in your web.config) you get an undesired effect:
Let's say that the 404 page you set forces a 404 status code like that...

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<script runat="server">

    void Page_Load(object o, EventArgs e)
        Response.StatusCode = 404;
        lbl.Text = Response.Status;
<html xmlns="" >
<head id="Head1" runat="server">
    <title>404 - Not Found</title>
        <asp:Image runat="server" ID="img" ImageUrl="~/Images/Icons/ico_warning.gif" AlternateText="404" ImageAlign="Middle" />
        <asp:Label runat="server" ID="lbl" Font-Bold="true" />

What you'll get is first a 302 status code (that means "redirect") and then the 404 one! (you can test it using Fiddler)

* That is to avoid in order to please search engines! *

Here it comes my solution...
The idea is to intercept a 404 HttpException via HttpModule and return the content of the 404 page written above.

Here's the IHttpModule implementation code:

using System;
using System.Web;

namespace PacemWebSite.BLL.Web
    class PacemHttpModule : System.Web.IHttpModule
        public void Dispose()

        public void Init(HttpApplication context)
            // putting a listener to the error event:                    
            context.Error += new EventHandler(context_Error);

        void context_Error(object sender, EventArgs e)
            HttpApplication app = (HttpApplication)sender;
            Exception lastError = app.Server.GetLastError();    
            HttpException he = lastError as HttpException;        
            // handling only HttpExceptions (and 404 in particular):
            if (he != null)
                int httpErrorCode = he.GetHttpCode();
                if (httpErrorCode == 404)
                    // clearing the error in order to avoid the exception to be thrown:
                    string fofPage = "~/Pages/404.aspx";
                    // setting/changing the handler for the current response:
                    app.Context.Handler = System.Web.UI.PageParser.GetCompiledPageInstance(fofPage, app.Server.MapPath(fofPage), app.Context);

Obviously, you must add your custom HttpModule to your Web.config as usual:

    <add name="FourOhFourModule" 
    type="PacemWebSite.BLL.Web.PacemHttpModule, PacemWebSite"/>

Now the response will be search engines pleasant with its straight 404!...

404 response

Take care. Bye.


  • Re: 404 vs 302 ASP.Net Custom Errors

    Scott Thursday, March 22, 2007 4.00

    This is good. I moved it to the Application_Error event handler in the global.asax codebehind file. Means the code is repeated throughout different projects but means I don't have to register a module each time either or modify the module to allow configuration changes from the web.config file.

  • Re: 404 vs 302 ASP.Net Custom Errors

    CMerighi Thursday, March 22, 2007 0.00

    Sure. It's about personal preferences... I love configurable modular environments: so that I just move my libraries and set (or not) this or that feature with relevant settings' values. Cheers!

  • Re: 404 vs 302 ASP.Net Custom Errors

    Luke Wednesday, August 08, 2007 5.00

    i couldn't get this to work, unfortunately. i managed to fix it by adding: handler.ProcessRequest(app.Context); it seems like in your code above you are relying on ASP.NET to call this for you. for some reason it doesn't for me...

  • Re: 404 vs 302 ASP.Net Custom Errors

    charles k Wednesday, August 15, 2007 4.00

    I'm new to ASP.NET. I'd like to implement your solution. What would I name the class file? Where would I save the class file? (App_Code > BLL). When adding the custom HttpModule reference in web.config what is the significance of the content in the type="a,b" attribute.

  • Re: 404 vs 302 ASP.Net Custom Errors

    Walter Monday, July 14, 2008 0.00

    Ciao, ho trovato molto interessante il tuo articolo ma ho provato a riprodurlo e non funziona (nelle mie pagine). Sono un neofita di ASP.NET e fino alla riga string fofPage = "~/Pages/404.aspx"; tutto ok dopo cominciano i guai. Potresti darmi qualche dritta ??? Grazie in anticipo, Walter.

  • Re: 404 vs 302 ASP.Net Custom Errors

    Mckensy Tuesday, September 23, 2008 4.00

    Good point but what will happens on a HIGTH traffic enviroment. Processing all HTTTPrequest could cause a massive deadlock :(

  • Re: 404 vs 302 ASP.Net Custom Errors

    CMerighi Tuesday, September 23, 2008 0.00

    @Mckensy: well, I consider it a lightweight procedure which - besides - only runs when an exception of type <i>HttpException</i> and with code <i>404</i> occurs. If I couldn't customize my site's "not-found-page" and will notice slow responses, I don't think I'll put the blame on this piece of code. But, if you know about issues I should keep in mind, better performing code or alternative solutions please let me know!... Thank you.

  • Re: 404 vs 302 ASP.Net Custom Errors

    Netguy Wednesday, May 06, 2009 5.00

    This is great and I'm using it in my website, thanks for sharing. I had to add a call to ProcessRequest like Luke suggested and it worked. However I encountered another problem: it is a requirement that i can access session state in the 404 page, but when the 404 is caused by my Url Rewriter (this is the url rewriting from and fires at the BeginRequest event which is before session is created). Session is null at this stage but also remains null, and I cannot find a way to make the system generate it. I tried deriving this HttpModule from IRequiresSessionState, but still nothing. Any suggestions? any help would be much appreciated..!

  • Re: 404 vs 302 ASP.Net Custom Errors

    Matt Tuesday, May 19, 2009 0.00

    I just moved Response.StatusCode = 404; to Page_Init, and I don't get the 302 before the 404.

  • Re: 404 vs 302 ASP.Net Custom Errors

    Kapil Tuesday, September 22, 2009 5.00

    I tried this, it worked fine on my development machine but when i deployed it on production, it is not doing anything. Could you please let me know what to do to get it worked on production. I am using IIS 6.0 and windows server




Cristian Merighi facebook twitter google+ youtube

Latest articles

Top rated


Where am I?


Cristian Merighi facebook twitter google+ youtube

I'm now reading