Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

    Introduction:



          When developing a web application, it is very important to optimize your application for search engines because a huge amount of traffic to website comes from search engines. ASP.NET MVC 3 support some Search Engine Optimization(SEO) features like friendly URLs, permanent redirect, etc. Friendly URLs is generated by a routing system in ASP.NET MVC 3. But in this routing system, multiple distinct URLs can point to a single action method, which result in duplicate content.  In this article, I will show you this(duplicate content) issue and then I will show you how to solve this issue. 

 

    Description:

 

          For SEO, it is important that every URL has its own unique and original content. So, we need to make sure that every single URL has its own unique content. But this is not the case with default ASP.NET MVC 3 application. The HomeController.Index action method of a new ASP.NET MVC 3 application can be pointed out by many distinct URLs. Some of them include,

          http://abc.com (Default one)
          http://abc.com/ (Trailing Slash)
          http://abc.com/Home (With Controller)
          http://abc.com/Home/Action (With Controller and Action)
          http://abc.com/home/Action (Different Case)
          and so on 

           This shows that an action method in ASP.NET MVC 3 can be pointed by many distinct URLs which is very bad for SEO perspective. One way to solve this issue is to use IIS URL Rewrite Extension. But this is complex and need to do a lot of work in your side. So, I have a created another solution by leveraging ASP.NET MVC 3 global filter. Just add this filter class in your application,

 

        public class RemoveDuplicateContentAttribute : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                var routes = RouteTable.Routes;
                var requestContext = filterContext.RequestContext;
                var routeData =requestContext.RouteData;
                var dataTokens = routeData.DataTokens;
                if (dataTokens["area"] == null)
                    dataTokens.Add("area", "");
                var vpd = routes.GetVirtualPathForArea(requestContext, routeData.Values);
                if (vpd != null)
                {
                    var virtualPath = vpd.VirtualPath.ToLower();
                    var request = requestContext.HttpContext.Request;
                    if (!string.Equals(virtualPath, request.Path))
                    {
                        filterContext.Result = new RedirectResult(virtualPath + request.Url.Query, true);
                    }
                }
                base.OnActionExecuting(filterContext);
            }
        }

  

           Then register this filter inside the global.asax.cs file,

 

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new RemoveDuplicateContentAttribute());
        }

 

           The RemoveDuplicateContent filter get the current RequestContext and RouteData. Then this filter will add a DataToken for area with empty value if there is no DataToken for area present in the current RouteData. This is important for generating a correct URL. Next, this filter will get the virtual path of current RouteData using the routing system and then convert this virtual path into lower case. Next, this filter will compare this lower case virtual path with current request path. If they are not matched then this filter will permanently redirect the current request to the lower case virtual path. In this way, your application URL for an action method will remain unique and you can easily solve the duplicate content issue.   

 

        Summary:

 

          For Search Engine Optimization (SEO), it is important to remove duplicate content because when there are identical content on the internet at more than one place then it will become difficult for search engines to decide which version for a given search query is more relevant. In this article, I showed you how to remove the duplicate content issue in ASP.NET MVC 3 application. Hopefully you will enjoy this article too.

 

Published Monday, December 19, 2011 12:50 PM by imran_ku07
Filed under: , ,

Comments

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Wednesday, December 21, 2011 6:03 AM by ASP.NET Development

Thank you for sharing this valuable information as after this I was able to carry out many problem regarding duplicate content issue in .net platform.

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Tuesday, January 17, 2012 3:08 PM by Seguro Automovel

Exactly what I was looking for. Before that I was strougling with IIS Rewrite. Thanks.

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Friday, February 24, 2012 5:42 PM by Bart Calixto

with this using @Html.Action("ActionName","ControllerName")

throw an exception:

Child actions are not allowed to perform redirect actions.

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Sunday, February 26, 2012 8:15 AM by imran_ku07

@Bart Calixto,

I don't think this is possible, can you provide a repro. BTW, there is no need to use this trick in child action. Just use filterContext.IsChildAction check.

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Monday, April 9, 2012 5:38 AM by Eric Lewis

After all many searches, I got the solution of duplicate content url problem in my website from your article. Thank you Imran

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Wednesday, May 9, 2012 7:25 PM by Solved the issue with Ajax and Html.Action

All you have to do is simple wrap all the code in a if statement that checks for IsChildAction and also isAjaxRequest and  code is bellow

if (!filterContext.IsChildAction && !filterContext.HttpContext.Request.IsAjaxRequest())

           {

               var routes = RouteTable.Routes;

               var requestContext = filterContext.RequestContext;

               var routeData = requestContext.RouteData;

               var dataTokens = routeData.DataTokens;

               if (dataTokens["area"] == null)

                   dataTokens.Add("area", "");

               var vpd = routes.GetVirtualPathForArea(requestContext, routeData.Values);

               if (vpd != null)

               {

                   var virtualPath = vpd.VirtualPath.ToLower();

                   var request = requestContext.HttpContext.Request;

                   if (!string.Equals(virtualPath, request.Path))

                   {

                       filterContext.Result = new RedirectResult(virtualPath + request.Url.Query, true);

                   }

               }

           }

# re: Solving Duplicate Content with Distinct URLs Issue in ASP.NET MVC

Tuesday, June 12, 2012 8:37 AM by avibpl

Gr8