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

Dan*_*eny 23 c# asp.net asp.net-mvc razor

编辑:现在我需要真正解决这个问题,我做了一些调查,并想出了一些减少重复内容的东西.我在我的博客上发布了详细的代码示例:使用ASP.NET MVC减少重复内容

第一篇文章 - 如果我标记错误或标记错误,请轻松一下:P

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

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

您可以设置默认控制器/操作以满足对域根目录的请求.假设我们选择HomeController/Index.我们最终提供以下提供相同内容的网址:

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

现在,如果人们开始链接到这两者,那么PageRank将被拆分.谷歌也会认为它是重复的内容,并惩罚其中一个,以避免重复他们的结果.

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

  • mydomain.com/Home/Index
  • mydomain.com/home/index
  • mydomain.com/Home/index
  • mydomain.com/home/Index
  • (列表还在继续)

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

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

可能?

Gab*_*ner 11

我也在研究这个问题.我显然会顺从ScottGu.我谦卑地提供了解决这个问题的方法.

将以下代码添加到global.asax:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

一个很好的问题!

  • 据我所知,这有潜在的缺点.打开Chrome(或其他具有良好调试功能的浏览器)并注意所有对图像,样式表,javascript等的请求都被重定向(假设您将它们放在名为"Content"或其他任何内容的文件夹中.)您不希望浏览器必须将这些资产的请求数量增加一倍,因此要么确保它们是小写的,要么不为实际不是路由的链接发送301s. (4认同)

Dan*_*eny 9

除了在这里发帖,我还通过电子邮件向ScottGu发送电子邮件,看他是否有好的回复.他给出了一个为路由添加约束的示例,因此您只能响应小写网址:

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());
    }
Run Code Online (Sandbox Code Playgroud)

并且在寄存器路由方法中:

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() }
    );
}
Run Code Online (Sandbox Code Playgroud)

这是一个开始,但是我希望能够从Html.ActionLink和RedirectToAction等方法更改链接的生成以匹配.


Ane*_*lou 3

撞!

MVC 5现在支持仅生成小写 URL 和常见的尾部斜杠策略。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.LowercaseUrls = true;
        routes.AppendTrailingSlash = false;
     }
Run Code Online (Sandbox Code Playgroud)

另外,在我的应用程序中,以避免不同域/IP/字母大小写等上的重复内容...

http://yourdomain.example/en

https://yourClientIdAt.YourHostingPacket.example/

我倾向于基于PrimaryDomain -协议-控制器-语言-操作来生成规范 URL

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);
}
Run Code Online (Sandbox Code Playgroud)

然后,如果当前请求 URL 不匹配,您可以使用@Gabe Sumner 的答案重定向到操作的规范 URL。