4 Kasım 2011 Cuma

MVC için SEO - 301 Redirect

Problem

Arama motorları web üzerinden ki aynı içeriğe birden fazla url ile ulaşılması durumunda tekrarlanan içerik olarak algılamaktadır. Arama motorları sitenizi tararken www'li e www'siz iki ayrı içeriği algılarlar. Yani http://www.siteniz.com/sayfa1.html ve http://siteniz.com/sayfa1.html  arama motorları için iki farklı tekrar edilen içeriktir. Bu durumda arama motorları tüm sitenizi tekrar eden içerik olarak algılar ve sitenizin bulunabilirliği azalır.

301 Redirect

Yapmanız gereken sitenizin www'li veya www'siz versiyonundan birini seçip gelen istekleri  diğer versiyona yönlendirmektir. Genellikle www'li versiyon kullanılmaktadır. Bende örnek olarak www'siz versiyondan gelen istekleri www'li versiyona yönlendireceğim. Yapmamız gereken gelen tüm istekleri kontrol edecek bir MvcHandler yazmak. MvcHandler'ımız gelen istekleri kontrol edecek ve istek adresinde www yoksa isteği www'li versiyona yönlendirecek.

Mvc 301 Redirect

   MvcHandler'lar Global.asax içinde yaptığımız Route tanımlarına eklenen nesnelerdir. MvcHandler bir Rooute işlemi çalışırken hangi Controller'ın seçilmesi gerektiğine karar verirler. Bu işlemi yapabilmek için tüm isteklerin başında çalışırlar. Mvc gelen isteğe göre önce hangi Route tanımının çalışması gerektiğine karar verir daha sonra Route içinde tanımlı Handler'larda hangi Controller sınıfının çalışması gerektiğine karar verir. Böyle her hangi bir Router için tüm istekler "Handle" edebileçeğiniz yer MvcHandler'dır.

Bizim problemimizde www'siz gelen tüm istekleri www'li versiyona çevirecek bir MvcHandler yazmamız gerekmektedir.

[cs]

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

        protected override IAsyncResult BeginProcessRequest(
            HttpContext httpContext,
            AsyncCallback callback, object state)
        {

            if (!httpContext.Request.Url.AbsoluteUri.Contains("://www."))
            {

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

            return base.BeginProcessRequest(
                httpContext, callback, state);
        }
    }

Mvc 301 Redirect

Yukarıda RedirectHandler içinde istek olarak gelen adresde www yoksa www'li versiyonuna yönlendirme yaptık. Fakat yönlendirmeden MVC sitemizde ki Route tanımlarının haberi bulunmamaktadır. Tüm Route tanımlarımıza RedirectHandler'ı kullanmaları gerektiğini söylememiz gerekmektedir. Yani tüm Route tanımlarımıza yazdığımız RedirectHandler ile çalışarak gerekli Controller'ı seçmesini söylemeliyiz.

[cs]

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("Content/{*pathInfo}");

            routes.MapRoute(
                "DefaultController",
                "{controller}/{action}/{id}",
                new {controller = "Home", action = "Index",id=UrlParameter.Optional});

            RouteHandler<RedirectHandler>.Assign(RouteTable.Routes);

Global.asax içinde sitemizde bulunan tüm Route tanımlarına RedirectHandler ekledik. Burada kullandığım RouteHandler sınıfı verilen MvcHandler tipini tüm Route tanımlarına eklemekte sorumludur. Yani RouteHandler sınıfı MvcHandler sınıflarını Route listelerine ekleyebilecek yardımcı bir sınıfdır.

[cs]

public class RouteHandler<THttpHandler> : MvcRouteHandler
    where THttpHandler : MvcHandler
    {
        public RouteHandler(IControllerFactory controllerFactory)
            : base(controllerFactory) { }
        public static void Assign(RouteCollection routes)
        {
            using (routes.GetReadLock())
            {

                var routeHandler
                    = new RouteHandler<THttpHandler>(
                        ControllerBuilder.Current.GetControllerFactory());

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

                    route.RouteHandler = routeHandler;
                }
            }
        }
    }

Sonuç

SEO için aynı içeriğin tek bir adresi olması gerekmektedir. Sitemizin www'siz adreslerini www'li adrese yönlendirmemiz gerekiyor. Bir MvcHandler yazarak bu işlemi gerçekleştirdik. Mvc sitemizde bulunan tüm Router tanımlarına bu handler'ı ekledik. Bu örnekte tüm isteklerde çalışacak bir MvcHandler yazmayı ve sitemizin Router tanımlarına eklemeyi gördük. Ayrıca SEO için önemli bir problemide çözmüş olduk. Ayrıca 301 Redirect mekanizması sadece adrese www eklemek için kullanılmaz. Eski adresin yeni adrese yönlendirilmesi işlemindede kullanılır.

Hiç yorum yok: