Saturday 19 April 2008

For When You Move Your Site

How many of us often end up rebuilding our site's either from one techonology to another, php to ASP.Net or ASP to ASP.Net, my guess is quite a few as I have done this a few times within the last year.


When rebuilding sites you often find that unless you map the old file extension or urls to the new ones your Google rating / ranking is hit as Google, and other search bots will encounter 404 errors instead of the pages they were expecting.

Now the best way when changing your site or even moving pages is to give the user and searchbots a pointer to where the new files are. A signpost if you will, this means they can find the new content and they will now know the new route to the content.


The HTTP specification defines two methods for these type of redirects. A 302 resposne is a temporary redirect, the content has moved for now but will be back in its original home at some point so don't update your references. The 301 status code however is a Moved Permanently redirect. If you serve this up as part of your response header and the new location then a user will be redirected to the new content. If Searchbots receieve this then they update all your stored links in their database to the new address.


What this results in is that your search listings all now point to the new address and you won't experience a drop in you page rank or have people going to 404 pages from a search listing.


Now this is great, however the issue often is how can I make these 301 redirects, do i have to manually add in pages to my new site that redirect to the new pages? In the past I have done this, where all i needed to do was redirect 1 or 2 pages, however last night I needed to cater for a site that had over 12 pages. Manually doing this was not an option.

urlRedirects

So last night I hacked together a simple HTTPHandler. urlRedirects. This HTTPHandler recieves requests and looks at XML file to see if it has a redirect for it. If it does it returns a 301 Header, if it doesn't it returns a 404 header. If the site has a custom 404 file it also returns this, otherwise a generic 404 message is returned.


The HTTP Handler is quite simple, to handle interacting with the XML file and filtering easily I used LINQ. I love LINQ at the moment and will hopefully post on how I've been using it, and learning to use it at another date. The rest of the code then just deals with serving the correct response header and content.

Using urlRedirects

Configuring Your .Net Web Application

If you want to use this project first get the DLL and reference it into your project. Next create yourself an XML file for your redirects, I called mine xmlredirects.xml


Next you need to define your redirects in the following XML Structure:


<?xml version="1.0" encoding="utf-8" ?>
<redirects> 
<redirect originalurl="/loadpage.php?id=7" redirecturl="/page.aspx?key=7" />
</redirects>

So your root node is <redirects> and this contains children node's redirect. Each redirect node has two attributes, originalurl and redirecturl. It is worth noting that the redirects uses the path and querystring so you can have page.php?key=something.


Once you have created your new file in your applications web.config you need to add a new application setting. XmlRedirectsLocation


<add key="XmlRedirectsLocation" value="~/xmlredirects.xml" />

Now you have the DLL references and the XML file created and available we now need to tell the .Net engine to pass any files of our choosing to our new handler. In my example I want to redirect PHP files so to do this I create a new HTTPHandler in my web.config


<add verb="*" path="*.php" type="mjjames.httphandlers.UrlRedirects, UrlRedirects" />

Now this tells the .Net engine what to do with PHP files but your webserver by default will not be passing PHP files to the .Net engine. The next step is to configure IIS to pass your file type to the .Net engine. Again I'll use PHP for my examples.

Configuring IIS

I assume most people will be using IIS6 however configuring it IIS7 is also as easy which I'll comment on in a moment.

IIS6

First of all bring up the properties menu for your site and navigate to the home directory tab. Once here click the configuration button which is in the application settigns area. This will bring up a new window.


The first tab mappings is the one we want to deal with. We want to map PHP files to the ASP.Net engine, so click add. In the new dialogue box we need to enter the ASP.Net isapi dll as our executable, C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll in my case. Then the file extension to send to it, in my example .PHP You can finally configure which VERBS it responds too, I went with the usual .Net ones GET,HEAD,POST,DEBUG. Click OK and then it's time to test your site.


Hopefully you'll find you new directs will kick in and you should see your new content.

IIS7

I found configuring the redirects for IIS7 easier, choose your site and then click on handler mappings.


This then brings up a list of the configured mappings, choose "add managed handler".

On the new window that pops up enter the request path, .php in my example. Then you can choose the handler from the drop down box: mjjames.httphandlers.UrlRedirects. Notice that for IIS7 you don't pass the request to the .Net isapi filter, you pass it straight to the handler. IIS7 is very cool ;) You can then name the new handler mapping for ease and if you want you can configure your request restricitons but this is optional.

That's it, I hope you find the URLRedirects useful, let me know any feedback / feature requests and I'll see if I can accommodate them.

Download urlRedirects

1 comment:

Unknown said...

Hi Michael,

I saw your urlRedirect code and thought it would come in handy as we move our sites from php to .net technology.

However, have followed your instructions I can't seem to get it to work. I get the following stack trace:

[NullReferenceException: Object reference not set to an instance of an object.]
mjjames.httphandlers.UrlRedirects.getRedirect(String sUrl) +63
mjjames.httphandlers.UrlRedirects.performRedirect(HttpContext context) +43
mjjames.httphandlers.UrlRedirects.ProcessRequest(HttpContext context) +5
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +358
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64


I don't know whether it's to do with the structure because our sites use a custom built framework, which selects a set of data and style information based on the url used to visit the site.

example:

visitor > www.domain-a.com > loads domain a style information and data

visitor > www.domain-b.com > loads domain b style information and data

This being the case we have a main web.config and a web.config file specific to each site which overides and tweaks settings in the main file depending on our needs.

basically what I am trying to do is add a line to each site specific web.config file which points to a respective xml containing information about redirects; esentially a different set of redirects per site on the framework.

How I went about implementing:

I have a bin folder containing other .dll libraries where I have placed your urlRedirects.dll

I put the reference to the .php handler in the main web.config file

I have placed the XmlRedirectsLocation appsetting inside each of the site specific web.config files which reference the xml file in accordance with your example.

I have tried on both IIS 6 and IIS 7 on two dirrerent machines.

Have you got any thoughts, It would be great to get it sorted.

Thanks