[updated 1st Sept 2007 21:49 with some minor changes]
This question came up on the
ASP.NET forum:
"I've Google a fair bit about this, but I'm still confused. I have a
static site built with html that I am migrating to ASP.NET 2.0.
However, I don't want links to break, and need to redirect from all the
old pages to the new ones. As the new ones will be generated
dynamically, the urls will change a lot: it won't simply be a case of
the the url changing from .htm to .aspx.I've heard that using the metatag of the .htm page is dangerous with
regards to search engine crawlers. What is the best way of having this
redirect happen? Is it just going through and putting a manual link on
all the old .htm pages? Or is there an automatic way?"
There are lots of ways you can handle redirects and newly named pages in HTML:
- Meta refresh: <meta http-equiv="refresh" content="0;url="http://www.ubuntu.com">
- Javascript: <script type="text/javascript">document.location="http://www.microsoft.com"</script>
- IIS Mapping: You can tell IIS to process files named "html" using ASP.NET. So you can have .NET running behind the scenes in "html" files !
But for a situation like the one above where you have a lot of legacy links to support, I prefer to keep everything centralized and let a custom 404 page do the work. Here's how:
- Create a new .aspx page called "404.aspx". Add some friendly error message to the page, and even associate it with a pre-existing Master Page, if you're using them.
- Update the <customerrors> section of your web.config as follows:
<customerrors mode="On" defaultredirect="GenericErrorPage.htm">
<error statuscode="403" redirect="NoAccess.htm"></error>
<error statuscode="404" redirect="404.aspx"></error>
</customerrors>
- Add a new <sectionGroup> to your web.config, along with your section containing you name/value pairs
<configsections>
...
<sectiongroup name="legacyRedirects">
<section name="urls" type="System.Configuration.NameValueSectionHandler">
</section>
</sectiongroup>
</configsections>
<legacyredirects>
<urls>
<add key="about.html" value="About.aspx">
<add key="contact.aspx" value="contact2000.aspx">
<add key="/Website1/about.html" value="About.aspx">
<add key="news.html" value="news/bignews.asp">
<!-- For off-site links, change to Response.Redirect -->
<add key="/Website1/home.html" value="http://our.new.site.aspx">
</legacyredirects>
- Finally, add the following code to your 404.aspx.cs (code behind)
//Sample code only -- needs to be refactored for production
using System;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
public partial class _404 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string aspxerrorpath = null;
//TODO: refactor out and clean up all these if null if !null checks
try
{
aspxerrorpath = base.Request.QueryString["aspxerrorpath"];
}
catch(NullReferenceException ex)
{
//nothing from a .net 404
}
if (aspxerrorpath == null)
{
//is IIS giving us a 404 ?
aspxerrorpath = base.Request.ServerVariables["QUERY_STRING"];
if (aspxerrorpath != null)
{
//clean up querystring
//i.e. 404;http://localhost:80/about.htm
Regex regex = new Regex(@".*http.*:\/\/[^/]*/");
aspxerrorpath = regex.Replace(aspxerrorpath, "");
}
}
if(aspxerrorpath != null)
{
//strip out any leading slashes in file names ("/Default.aspx" --> "Default.aspx")
Regex regex = new Regex(@"^\/");
aspxerrorpath = regex.Replace(aspxerrorpath, "");
NameValueCollection config =
(NameValueCollection)ConfigurationManager.GetSection("legacyRedirects/urls");
foreach (string legacyPage in config)
{
base.Response.Write("Trying to match:" + aspxerrorpath
+ " with configuration:" + legacyPage + "
");
if (aspxerrorpath.ToLower() == legacyPage.ToLower())
{
base.Server.Transfer(config[legacyPage]);
}
}
}
}
}
Last but not least, update IIS's 404 to point to your new 404.aspx. You don't need to do this when running in the Visual Studio Development Server (the "F5 Server"), but you'll have to do this in a production environment.

Download sample code here:
404_Redirect.zip (4.7kb)