Sat, 1 August 2009

Recently this site has changed structure, it's still being updated and pages are not where they used to be. My "SEO Doctor" tells me that I need to keep a track on the changes and nicely redirect requests to the new location and also antix.co.uk -301> www.antix.co.uk, the later is what I will be doing here.

This is an ASP.NET MVC site and therefore I need to interupt the Route handling to achieve this, so, I need an MvcHandler and an IRouteHandler for the job

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace Antix.Web.Mvc {

  /// <summary>
  /// <para>Redirecting MVC handler</para>
  /// </summary>
  public class RedirectHandler : MvcHandler {

  public RedirectHandler(RequestContext requestContext)
   : base(requestContext) { }

  protected override void ProcessRequest(HttpContextBase httpContext) {

   if (httpContext.Request.IsLocal) {
    base.ProcessRequest(httpContext);
   } else {

    // check for domain without www
    if (!RequestContext.HttpContext.Request.Url.AbsoluteUri
                                    .Contains("://www.")) {

     httpContext.Response.Status = "301 Moved Permanently";
     httpContext.Response.StatusCode = 301;
     httpContext.Response.AppendHeader(
      "Location",
      RequestContext.HttpContext.Request.Url.AbsoluteUri
                                    .Replace("://", "://www.")
     );

     return;
    }

    base.ProcessRequest(httpContext);
   }
  }
 }
}

This will check for lack of www in the url and plop one in, then pass the HttpContext on to the base ProcessRequest function for the difficult stuff.

Now for the IRouteHandler

using System.Linq;
using System.Web;
using System.Web.Routing;

namespace Antix.Web.Mvc {
 public class RedirectRouteHandler : IRouteHandler {
  
  public IHttpHandler GetHttpHandler(RequestContext requestContext) {
   
   return new RedirectHandler(requestContext);
  }

  /// <summary>
  /// <para>Assign route handler to all routes</para>
  /// </summary>
  /// <param name="routes">Routes</param>
  public static void Assign(RouteCollection routes) {
   using (routes.GetReadLock()) {

    foreach (var route in routes
      .OfType<Route>()
      .Where(r=>!(r.RouteHandler is RedirectRouteHandler))) {

     route.RouteHandler = new RedirectRouteHandler();
    }
   }
  }
 }
}

This is responsible for creating the RedirectHandler as required. It also contains a static function for assigning its self as the handler for each appropriate route, this will be called from the Global.asax on application startup, see below.

public class MvcApplication : HttpApplication
{
 protected void Application_Start()
 {
  RegisterRoutes(RouteTable.Routes);
  RedirectRouteHandler.Assign(RouteTable.Routes);

 ...
 }
}

Well there you go, next, I'll be adding a method for storing moved pages in a file which can be checked and redirected where needed, it may be that this is done only when a page is not found - not sure yet - isn't coding exciting!


ASP.NET MVC, 301 Redirect, Development

Comments

10 Mar 2010

Dean

Nice work, this is simple and effective. Thanks!


Please feel free to add your comments here


(required)


(required, not shown)

(required)