Welcome to Bangladesh Microsoft Technology Community Sign in | Join | Help

ASP.NET MVC Tips: 301 Redirect non-www versions of URL to www.

Search Engine Optimization guides, recommends to have one version of a URL of the same content. Search engines may pickup www and non-www versions of URL as 2 separate URLs, i.e. http://xyz.com/page1 may be considered different to http://www.xyz.com/page1. It is a good idea to pick on of these URLs as preferred and use 301 redirects to send traffic from the other URLS to the preferred URL. Today we will pickup www version of URL as our preferred URL and look at how we can redirect the non-www version of the URL to our preferred URL structure using ASP.NET MVC.


  

We can achieve the above by writing a custom handler that extends from the MvcHandler. We are basically interested in the ProcessRequest method where we can get hold of the non-www version of the URL to replace it to the www. version of URL.

    public class The301GlobalHandler : MvcHandler
    {
        public The301GlobalHandler(RequestContext requestContext) : base(requestContext) { }

        protected override void ProcessRequest(HttpContextBase httpContext)
        {
            //We do not want this handler to process local requests
            if (httpContext.Request.IsLocal)
                base.ProcessRequest(httpContext);
            else
                ProcessExternalRequest(httpContext);
        }

        private void ProcessExternalRequest(HttpContextBase httpContext)
        {
            bool urlChanged = false;
            string url = RequestContext.HttpContext.Request.Url.AbsoluteUri;
            //Check for non-www version URL
            if (!RequestContext.HttpContext.Request.Url.AbsoluteUri.Contains("www"))
            {
                urlChanged = true;
                //change to www. version URL
                url = url.Replace("http://", "http://www.");                    
            }
            ProcessExternalRequest(url, urlChanged, httpContext);
        }

        private void ProcessExternalRequest(string url, bool urlChanged, HttpContextBase httpContext)
        {
            if (urlChanged)
            {
                //mark as 301
                httpContext.Response.Status = "301 Moved Permanently";
                httpContext.Response.StatusCode = 301;
                httpContext.Response.AppendHeader("Location", url);
            }
            else
                base.ProcessRequest(httpContext);
        }
    }

The above code is self explanatory, we are checking if the Request is local or external, we are only interested on external URLs. Next we check, whether the RequestContext.HttpCOntext.Request.Url.AbsoluteUri contains a "www" or not. If it do not contain a "www" we go and inject a "www" to the URL to convert the non-www version of URL to a www. version URL. Then we mark the previous response to a 301, which indicates that the previous URL has been permanently removed and all future requests should be directed to the given new URL. 

We have developed our core handler above, however we need a wrapper IRouteHandler class to get the above The301GlobalHandler to work within the MVC Framework. This wrapper class is responsible to return an instance of the The301GlobalHandler.

    public class Route301GlobalHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new The301GlobalHandler(requestContext);
        }
    }


We have got our Route301GlobalHandler ready, now we need all of our requests to go via this handler instead of the default. One easy way to do this, is to iterate through the route collection and  assign them to this Route301GlobalHandler during the Application_Start().

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
        Route301Global.ReAssignHandler(RouteTable.Routes);
    }
    public static class Route301Global
    {
        public static void ReAssignHandler(RouteCollection routes)
        {
            using (routes.GetReadLock())
            {
                AssignRoute301GlobalHandler(routes);
            }
        }

        private static void AssignRoute301GlobalHandler(IEnumerable<RouteBase> routes)
        {
            foreach (var routeBase in routes)
            {
                AssignRoute301GlobalHandler(routeBase);
            }
        }

        private static void AssignRoute301GlobalHandler(RouteBase routeBase)
        {
            var route = routeBase as Route;
            if (route == null) return;
            if (route.RouteHandler.GetType() != typeof(Route301Handler))
                route.RouteHandler = new Route301GlobalHandler();
        }
    }

Note, if you have other custom RouteHandler in your application, you will need to tweak this code, I am assuming all routes that will be mapped in the RegisterRoutes(RouteCollection routes) method uses the MvcHandler.

Conclusion

We have identified keeping one set of URL is important for SEO. Then we have looked at how we can 301 redirect non-www version of URL to www. version URL in ASP.NET MVC. Hope this saves you some time and thank you for being with me so far.

Published Monday, May 18, 2009 12:04 PM by Shahed

Comments

# ASP.NET MVC Archived Blog Posts, Page 1

Monday, May 25, 2009 9:08 PM by ASP.NET MVC Archived Blog Posts, Page 1

# re: ASP.NET MVC Tips: 301 Redirect non-www versions of URL to www.

Sunday, August 23, 2009 4:51 PM by AltafKhatri
Nice article. I was looking for this from some time. Just one correction:
private static void AssignRoute301GlobalHandler(RouteBase routeBase)
       {
           var route = routeBase as Route;
           if (route == null) return;
           if (route.RouteHandler.GetType() != typeof(Route301Handler))
               route.RouteHandler = new Route301GlobalHandler();
       }


Shouldnt Route301Handler be Route301GlobalHandler?

# Chevrolet Monza Ii Discount Pontiac Phoenix, Monza Coupon Lowest Prices

# Top Quality Club, E 100 Econoline Club Wagon Part Galaxie 500 Mustang Ii - 313.defutbolazo.com

# Relay Life May 9, Pam Relay Veirs - 380.jordanbrandallamerican.com

# 2001 Chevrolet Silverado 1500 Horsepower, G1500 0 60 - 275.defutbolazo.com

# R3500 Used Classified Gmc Yukon Xl, K15 K1500 Pickup Price Used Gmc Yukon Denali Xl - 7.akemet.com

Anonymous comments are disabled