24

编辑:现在我需要真正解决这个问题,我做了更多调查并想出了一些减少重复内容的方法。我在我的博客上发布了详细的代码示例:Reducing Duplicate Content with ASP.NET MVC

第一篇文章 - 如果我把它标记错或标记得很差,那就放轻松:P

在 Microsoft 的新 ASP.NET MVC 框架中,似乎有两件事可能会导致您的内容在多个 URL 上提供(Google 会对此进行惩罚并将导致您的 PageRank 在它们之间拆分):

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

您可以设置默认控制器/操作来为您的域根目录的请求提供服务。假设我们选择 HomeController/Index。我们最终得到以下提供相同内容的 URL:

  • 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 都区分大小写

可能的?

4

7 回答 7

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();
    }
}

一个很好的问题!

于 2008-10-04T20:57:29.117 回答
9

除了在这里发帖外,我还给 ScottGu 发了电子邮件,看看他是否有很好的回应。他提供了一个为路由添加约束的示例,因此您只能响应小写 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() }
    );
}

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

于 2008-10-04T20:35:44.153 回答
3

撞!

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

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

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

http://yourdomain.com/en

https://yourClientIdAt.YourHostingPacket.com/

我倾向于基于PrimaryDomain - Protocol - Controller - Language - Action生成规范 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);
}

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

于 2016-12-22T09:16:22.333 回答
2

我相信对此有更好的答案。如果您在页面标题中放置一个规范链接,例如:

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

然后谷歌只在他们的结果中显示规范页面,更重要的是,谷歌的所有优点都没有受到惩罚。

于 2012-06-22T20:31:40.457 回答
1

和你一样,我也有同样的问题;除了我不愿意接受全小写的 URL 限制,也不喜欢这种canonical方法(嗯,它很好,但不是单独的)。

我找不到解决方案,所以我们编写并开源了一个重定向类

使用它很简单:控制器类中的每个 GET 方法只需要在开头添加这一行:

Seo.SeoRedirect(this);

SEO 重写类自动使用 C# 5.0 的 Caller Info 属性来完成繁重的工作,使上面的代码严格地复制和粘贴。

正如我在链接的 SO Q&A 中提到的那样,我正在研究一种将其转换为属性的方法,但现在,它可以完成工作。

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

于 2012-11-06T06:55:40.873 回答
0

我真的不知道 8 年后你会有什么感觉,但是现在 ASP MVC 5 支持属性路由,以便于记住路由并解决 SEO 友好站点的重复内容问题

只需添加 routes.MapMvcAttributeRoutes(); 在您的 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();
    }
于 2016-01-26T03:11:14.777 回答
0

基于 Gabe Sumner 的回答,但没有 JS、图像和其他内容的重定向。仅适用于控制器操作。这个想法是当我们已经知道它的路线时,稍后在管道中进行重定向。为此,我们可以使用 ActionFilter。

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());

最好在 RouteCollection 上仍将 LowercaseUrls 属性设置为 true。

于 2018-08-03T06:26:12.720 回答