代码之家  ›  专栏  ›  技术社区  ›  Danny Tuppeny

如何避免ASP.NET MVC中由于不区分大小写的URL和默认值而出现重复内容?

  •  23
  • Danny Tuppeny  · 技术社区  · 17 年前

    编辑 当前位置现在我需要真正解决这个问题,我做了更多 调查并提出了一个解决方案 减少重复的事情的数量 所容纳之物我发布了详细的代码 我的博客上的示例: Reducing Duplicate Content with ASP.NET MVC

    第一篇帖子——如果我把它标错了或者贴错了标签,那就轻松一点:P

    在微软新的ASP.NET MVC框架中,似乎有两件事可能会导致您的内容在多个URL上被提供(这是谷歌的惩罚,并会导致您的PageRank被拆分):

    • 不区分大小写的URL
    • 默认URL

    • mydomain.com/
    • mydomain.com/Home/Index

    现在,如果人们开始链接到这两个页面,那么PageRank将被拆分。谷歌也会考虑复制内容并惩罚其中之一,以避免重复结果。

    除此之外,URL不区分大小写,因此我们实际上也为这些URL获取相同的内容:

    • mydomain.com/Home/Index
    • mydomain.com/home/index
    • mydomain.com/home/Index
    • (名单还在继续)

    所以,问题是。。。我如何避免这些处罚?我想:

    • 将默认操作的所有请求(301状态)重定向到同一url
    • 所有URL都区分大小写

    可能的

    7 回复  |  直到 15 年前
        1
  •  11
  •   Gabe Sumner    17 年前

    我也在做这个。在这件事上,我显然会听从斯科特格的。不过,我也谦虚地提出了解决这个问题的办法。

    将以下代码添加到 :

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        // If upper case letters are found in the URL, redirect to lower case URL.
        if (Regex.IsMatch(HttpContext.Current.Request.Url.ToString(), @"[A-Z]") == true)
        {
            string LowercaseURL = HttpContext.Current.Request.Url.ToString().ToLower();
    
            Response.Clear();
            Response.Status = "301 Moved Permanently";
            Response.AddHeader("Location",LowercaseURL);
            Response.End();
        }
    }
    

        2
  •  9
  •   Drew Noakes    15 年前

    除了在这里发帖外,我还给斯科特古发了电子邮件,看看他是否有好的回复。他给出了一个为路由添加约束的示例,因此您只能响应小写URL:

    public class LowercaseConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route,
                string parameterName, RouteValueDictionary values,
                RouteDirection routeDirection)
        {
            string value = (string)values[parameterName];
    
            return Equals(value, value.ToLower());
        }
    

    在注册路由方法中:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "home", action = "index", id = "" },
            new { controller = new LowercaseConstraint(), action = new LowercaseConstraint() }
        );
    }
    

        3
  •  3
  •   Community Mohan Dere    6 年前

    碰撞

    MVC5 现在只支持生成小写URL和公共尾随斜杠策略。

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.LowercaseUrls = true;
            routes.AppendTrailingSlash = false;
         }
    

    http://yourdomain.com/en

    https://yourClientIdAt.YourHostingPacket.com/

    主域 - 协议 控制器 - 语言 行动

    public static String GetCanonicalUrl(RouteData route,String host,string protocol)
    {
        //These rely on the convention that all your links will be lowercase! 
        string actionName = route.Values["action"].ToString().ToLower();
        string controllerName = route.Values["controller"].ToString().ToLower();
        //If your app is multilanguage and your route contains a language parameter then lowercase it also to prevent EN/en/ etc....
        //string language = route.Values["language"].ToString().ToLower();
        return String.Format("{0}://{1}/{2}/{3}/{4}", protocol, host, language, controllerName, actionName);
    }
    

    然后你可以用 @加布·萨姆纳

        4
  •  2
  •   Timbo    14 年前

    我相信有更好的答案。如果在页眉中放置规范链接,如:

    <link rel="canonical" href="http://mydomain.com/Home/Index"/>
    

    然后谷歌只在他们的搜索结果中显示规范页面,更重要的是,谷歌所有的好东西都会进入该页面而不会受到惩罚。

        5
  •  1
  •   Community Mohan Dere    9 年前

    像你一样, I had the same question canonical 这两种方法都可以(好吧,这很好,但不是靠它自己)。

    我找不到解决办法,所以我们 wrote and open-sourced redirect class

    使用它非常简单:控制器类中的每个GET方法只需在开始时添加这一行:

    Seo.SeoRedirect(this);
    

    正如我在有关的SO Q&A、 我正在研究将其转换为属性的方法,但现在,它完成了任务。

    该代码将强制URL使用一个大小写。大小写将与控制器方法的名称相同-您可以选择是要全部大写、全部小写,还是两者兼而有之(CamelCase适合URL)。它将对不区分大小写的匹配发出301重定向,并将结果缓存在内存中以获得最佳性能。它还将重定向尾部反斜杠(对索引列表强制,否则强制关闭),并删除通过默认方法名访问的重复内容( Index 在股票ASP.NET MVC应用程序中)。

        6
  •  0
  •   Asad Ali    10 年前

    加上 routes.mapmvcattributteroutes();在RouteConfig中,然后为每个操作定义一个且唯一的路由,如

        [Route("~/")]
        public ActionResult Index(int? page)
        {
            var query = from p in db.Posts orderby p.post_date descending select p;
            var pageNumber = page ?? 1;
            ViewData["Posts"] = query.ToPagedList(pageNumber, 7);         
            return View();
        }
        [Route("about")]
        public ActionResult About()
        {
            return View();
        }
        [Route("contact")]
        public ActionResult Contact()
        {
            return View();
        }
        [Route("team")]
        public ActionResult Team()
        {
            return View();
        }
        [Route("services")]
        public ActionResult Services()
        {
            return View();
        }
    
        7
  •  0
  •   Edwin Stoteler    8 年前

    public class RedirectFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var url = filterContext.HttpContext.Request.Url;
            var urlWithoutQuery = url.GetLeftPart(UriPartial.Path);
            if (Regex.IsMatch(urlWithoutQuery, @"[A-Z]"))
            {
                string lowercaseURL = urlWithoutQuery.ToString().ToLower() + url.Query;
                filterContext.Result = new RedirectResult(lowercaseURL, permanent: true);
            }
    
            base.OnActionExecuting(filterContext);
        }
    }
    

    请注意,上面的过滤器不会重定向或更改查询字符串的大小写。

    然后通过将ActionFilter添加到GlobalFilterCollection,将其全局绑定到所有操作。

    filters.Add(new RedirectFilterAttribute());