Подтвердить что ты не робот

Как избежать дублирования содержимого в ASP.NET MVC из-за нечувствительных к регистру URL-адресов и значений по умолчанию?

Изменить: теперь мне нужно решить эту проблему на самом деле, я сделал немного больше расследования и придумали количество вещей, чтобы уменьшить дубликат содержание. Я отправил подробный код образцы в моем блоге: Уменьшение Дублирование содержимого с помощью ASP.NET MVC

Первое сообщение - легко, если я отметил это неправильно или неправильно помечен: P

В новой структуре ASP.NET MVC Microsoft кажется, что есть две вещи, которые могут привести к тому, что ваш контент будет обслуживаться по нескольким URL-адресам (то, за что Google наказывает и приведет к разрыву вашего PageRank):

  • Нечувствительные к регистру URL-адреса
  • URL по умолчанию

Вы можете установить контроллер/действие по умолчанию для обслуживания запросов к корню вашего домена. Скажем, мы выбираем HomeController/Index. В результате мы получаем следующие URL-адреса, обслуживающие один и тот же контент:

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

Теперь, если люди начнут связываться с обоими из них, тогда PageRank будет разделен. Google также рассматривал бы это дублирование контента и наказывал одного из них, чтобы избежать дублирования результатов.

Кроме того, URL-адреса не чувствительны к регистру, поэтому мы фактически получаем один и тот же контент для этих URL-адресов:

  • mydomain.com/Home/Index
  • mydomain.com/home/index
  • mydomain.com/Home/index
  • mydomain.com/home/Index
  • (список можно продолжить)

Итак, вопрос... Как избежать этих штрафов? Я бы хотел:

  • Все запросы для перенаправления по умолчанию (статус 301) на тот же URL
  • Все URL-адреса будут чувствительны к регистру.

Возможные?

4b9b3361

Ответ 1

Bump!

MVC 5. Теперь поддерживается создание только строчных URL-адресов и общей политики косой черты.

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

Также в моем приложении избежать дублирования содержимого на разных доменах /Ip/Letter Casing и т.д.

http://yourdomain.com/en

https://yourClientIdAt.YourHostingPacket.com/

Я склонен создавать канонические адреса на основе PrimaryDomain - Протокола - Контроллер - Язык - Действие

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

Затем вы можете использовать ответ @Gabe Sumner для перенаправления на ваш канонический URL-адрес действия, если текущий URL-адрес запроса не соответствует ему.

Ответ 2

Помимо публикации здесь, я отправил по электронной почте 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() }
    );
}

Это начало, но 'd хотите иметь возможность изменять генерации ссылок из таких методов, как Html.ActionLink и RedirectToAction, чтобы соответствовать.

Ответ 3

Я тоже работал над этим. Я, очевидно, буду откладывать на 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();
    }
}

Отличный вопрос!

Ответ 4

Я считаю, что есть лучший ответ на этот вопрос. Если вы поместите каноническую ссылку в свою страницу, как:

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

Затем Google показывает только каноническую страницу в своих результатах, и, что более важно, вся доброта Google идет на эту страницу без штрафа.

Ответ 5

Как и вы, у меня был тот же вопрос; за исключением того, что я не хотел соглашаться на ограничение всех строчных URL-адресов, и мне не понравился подход canonical (ну, это хорошо, но не само по себе).

Я не мог найти решение, поэтому мы писали и открывали исходники перенаправить класс.

Использование его достаточно просто: каждый метод GET в классах контроллера должен добавить только одну строку в начале:

Seo.SeoRedirect(this);

Класс rewrite для SEO автоматически использует атрибуты Caller Info С# 5.0 для выполнения тяжелой работы, делая код выше строго скопируйте и вставьте.

Как я упоминал в связанном SO Q & A, я работаю над тем, как преобразовать его в атрибут, но на данный момент он выполняет свою работу.

Код заставит одно дело для URL. Случай будет таким же, как имя метода контроллера - вы выбираете, хотите ли вы все кепки, все ниже или сочетание обоих (CamelCase хорош для URL-адресов). Он будет выдавать 301 переадресацию для нечувствительных к регистру совпадений и кэширует результаты в памяти для достижения максимальной производительности. Он также перенаправляет трейлинг-обратную косую черту (применяется для списков индексов, принудительно отключается в противном случае) и удаляет дублирующийся контент, доступ к которому осуществляется по имени метода по умолчанию (Index в приложении ASP.NET MVC).

Ответ 6

Я действительно не знаю, как вы будете себя чувствовать через 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();
    }