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



编辑:现在我需要真正解决这个问题,我做了更多调查并得出减少重复的事物数量所容纳之物我发布了详细代码我博客上的示例:减少使用ASP复制内容。NET MVC

第一篇文章-如果我把这个标记错了或标记得不好,那就简单点:p

在微软的新ASP。NET MVC框架似乎有两件事可能会导致你的内容在多个URL上提供(谷歌会因此惩罚你,并导致你的PageRank在它们之间分裂):

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

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

  • example.com/
  • example.com/Home/Index

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

最重要的是,URL不区分大小写,所以我们实际上也为这些URL获得了相同的内容:

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

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

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

可能吗?

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

将以下代码添加到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();
    }
}

一个很好的问题!

除了在这里发帖,我还给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匹配。

颠簸!

MVC 5现在只支持生成小写URL和通用尾部斜杠策略。

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

也在我的应用程序上,以避免不同域名/Ip/Letter Casing等上的重复内容…

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

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

我相信有更好的答案。如果你在你的页头放一个规范的链接,比如:

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

然后谷歌只在他们的结果中显示规范页面,更重要的是,谷歌所有的优点都会免费进入该页面。

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

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

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

Seo.SeoRedirect(this);

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

正如我在链接的SO问答中提到的那样;A、 我正在研究将其转换为属性的方法,但目前,它已经完成了任务。

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

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

只需添加路线。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();
    }

基于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是个好主意。

相关内容

最新更新