404 Errors with .NET – An Alternate Method

Published on September 22, 2008 | Filed Under SEO

After my last post about 404 Errors with .NET, I decided that I would post an alternate method to 404 Error-Handling. I mentioned last time that the solution was to create an HTTP module, but this is not always the best solution for every web site setup. When you create 301 Redirections, you need to keep in mind that the first error message that a Search Engine sees will dictate what it does with the page, within its index.

I’m going to copy some of the information from my last post, because some of it is still relevant.


When you set up your website to have a custom 404 error page, even though your web browser directly takes you there, you’re actually hitting a 302 (Temporary Redirect) error page. Here are the headers I received from a test website I setup:

  HTTP/1.1 302 Found
  Server: ASP.NET Development Server/
  Date: Tue, 23 Sep 2008 00:33:31 GMT
  X-AspNet-Version: 2.0.50727
  Location: /DevPaper/404ErrorPage.aspx?aspxerrorpath=/DEVPAPER/X.ASPX
  Cache-Control: private
  Content-Type: text/html; charset=utf-8
  Content-Length: 175
  Connection: Close

Why is this bad? Well, a 302 error actually tells the spider crawling your website that the page will return there one day, thus causing your page to remain in the search engine’s index. Not only will this drive more people to pages no longer in existence, this will also cause your overall ranking within the search engine to get worse.

The solution we’re going to explore today is implementing a Global.asax file. If you already have one implemented, this might be an easy implementation for you. Just as with the HTTP Module, this method has its limitations, as well. We’ll explore later what the limitations of each are.

What is Global.asax?

Global.asax is a file, which can be implemented into any .NET website. IIS and the runtime compiler will automatically detect the file, so there is no need actual “implementing” the file; it works the same as Web.config. Unlike Web.config, Global.asax is used for actual programming and is fired before any code on the web page is. This is why it is such a good choice for handling 404, or other application events.

Adding Global.asax:

To add a new Global.asax file to your website, Right-click on your website project file and select “Add New Item”. In the dialog, select Global Application Class, make sure the name is Global.asax and press Add.

You should now have a funny-looking page, which has a page directive and Script tag with some pre-defined functions.

Thankfully for us, the Visual Studio team over at Microsoft decided not to thrown an exception with every method included. Instead of worrying about getting rid of rogue exceptions, we can get down to business and just start programming.

If you recall from my last post, we were only worried about the Error event with HTTP Module. The same holds true for our Global.asax file. The only difference here is that our method is already created for us.

Add the following lines into your Application_Error method:

  if (Server.GetLastError().ToString().Contains("does not exist"))
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", "/404Errors/404ErrorPage.aspx?aspxerrorpath=" + Request.Url.PathAndQuery);

What’s Next?

Actually, that’s it! Since Global.asax doesn’t actually have to be compiled, you can change it as you see fit. The only drawback is that changes to the Global.asax file will usually result in your web application requiring a quick restart. ASP.NET will handle this for you automatically, so you don’t have to worry about this. This is actually considered a major limitation for larger web applications, as it could take several minutes for your application to restart.

Here are the HTTP headers when I check for a non-existent page after the implementation:

  HTTP/1.1 301 Moved Permanently
  Server: ASP.NET Development Server/
  Date: Tue, 23 Sep 2008 01:34:37 GMT
  X-AspNet-Version: 2.0.50727
  Location: /404Errors/404ErrorPage.aspx?aspxerrorpath=/DEVPAPER/X.ASPX
  Cache-Control: private
  Content-Type: text/html
  Connection: Close

Quick Notes:

Since this was such a short implementation I want to take a moment to explain some of the differences between an HTTP Module and a Global.asax file.

HTTP Module:

  • Requires a compiled .dll file, thus requiring a different project file
  • Enabling and disabling is as simple as removing the reference from the main website’s Web.config file
  • Every application pool within the website will require the .dll file to be placed in a bin folder
  • Since code is in a .dll file, your source is secure and easily distributed
  • If you make an alteration to your code, the website may only be inaccessible for seconds


  • The file is not physically compiled, so it can be edited from any text editor
  • Has to be placed in the root folder of each application pool within the website
  • Enabling and disabling is highly difficult if your site requires several application pools
  • Since the code is editable from any text editor, your source is not secure
  • If you make an alteration to your code, the entire website may become inaccessible for several minutes

So there you have it! You now have two options for properly handling those pesky 404 errors. If you find that there may be a more efficient way to handle these, don’t hesitate to leave a comment!

~Derek Torrence

Leave a Reply