Wie kann ich doppelte Inhalte in ASP.NET MVC vermeiden aufgrund Groß- und Kleinschreibung URLs und Standardwerte?

StackOverflow https://stackoverflow.com/questions/170900

  •  05-07-2019
  •  | 
  •  

Frage

  

Bearbeiten : Jetzt muss ich dieses Problem für echte lösen, habe ich ein wenig mehr   Untersuchung und kam mit einem bis   Anzahl der Dinge doppelt zu reduzieren   Inhalt. Ich stellte detaillierten Code   Proben auf meinem Blog: Reduzierung   Duplicate Content mit ASP.NET MVC

Erste Post - gehen Sie einfach, wenn ich dies oben markiert haben falsch oder markiert es schlecht: P

In Microsofts neuen ASP.NET-MVC-Framework es scheint, gibt es zwei Dinge, die Ihre Inhalte dazu führen könnten, an mehreren URLs bedient werden (was Google bestraft und wird dazu führen, dass PageRank über sie aufgeteilt werden):

  • Case-insensitive URLs
  • Standard-URL

Sie können die Standard-Controller / Aktion für Anfragen an die Wurzel Ihrer Domain zu dienen. Lassen Sie uns sagen, dass wir Homecontroller / Index wählen. Wir am Ende mit der folgenden URLs den gleichen Inhalt serviert:

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

Nun, wenn Menschen diese beiden Verknüpfung starten dann würde PageRank geteilt werden. Google wäre es duplizieren auch prüfen, Inhalt und bestrafen einer von ihnen Duplikate in ihren Ergebnissen zu vermeiden.

Auf dieses werden die URLs nicht zwischen Groß- und Klein, so dass wir tatsächlich den gleichen Inhalt für diese URLs erhalten auch:

  • mydomain.com/Home/Index
  • mydomain.com/home/index
  • mydomain.com/Home/index
  • mydomain.com/home/Index
  • (die Liste geht weiter)

Also, die Frage ... Wie vermeide ich diese Strafen? Ich möchte:

  • Alle Anforderungen für die Standardaktion umgeleitet (301 Status) auf die gleiche URL zu
  • Alle URLs werden Groß- und Kleinschreibung

möglich?

War es hilfreich?

Lösung

Bump!

MVC 5 unterstützt jetzt nur Klein Urls und gemeinsame Slash Politik zu erzeugen.

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

Auch auf meiner Anwendung Duplicate Content auf verschiedene Domains / Ip / Letter Gehäuse usw. zu vermeiden ...

  

http://yourdomain.com/en

     

https://yourClientIdAt.YourHostingPacket.com/

Ich neige dazu, Canonical Urls basiert auf einer PrimaryDomain zu produzieren - Protokoll - Controller - Sprache - Aktion

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

Dann können Sie @Gabe Sumner Antwort auf Ihre Aktion kanonische URL zu umleiten, wenn die aktuelle Anforderung url nicht überein.

Andere Tipps

Ich war auch auf dieser Arbeit. Ich werde natürlich auf ScottGu auf diese aufzuschieben. Ich demütig meine Lösung für dieses Problem bieten auch though.

Fügen Sie den folgenden Code 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();
    }
}

Eine große Frage!

Neben Posting hier, ich mailte ScottGu zu sehen, ob er eine gute Antwort hat. Er gab eine Probe für die Zwänge zu Routen hinzufügen, so dass Sie konnte nur reagieren Urls in Kleinbuchstaben:

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

Und im Register Routen-Methode:

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

Es ist ein Anfang, aber ‚d in der Lage sein, um mit der Erzeugung von Verbindungen von Methoden wie Html.ActionLink und RedirectToAction zu ändern.

Ich glaube, es ist eine bessere Antwort. Wenn Sie einen kanonischen Link auf Ihrer Seite Kopf gestellt wie:

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

Google zeigt dann nur die kanonische Seite in ihren Ergebnissen und vor allem all der Güte Google geht auf dieser Seite ohne Strafe.

Wie Sie, hatte ich die gleiche Frage ; außer ich war nicht bereit, für eine All-Kleine URL Einschränkung zu regeln, und nicht wie der canonical Ansatz entweder (na ja, es ist gut, aber nicht allein).

Ich konnte keine Lösung finden, so dass wir schrieb und Open-Source- eine umleiten Klasse .

Unter Verwendung ist es einfach genug: jede GET-Methode in den Controller-Klassen am Start nur diese eine Zeile hinzufügen muss:

Seo.SeoRedirect(this);

Die SEO-Rewrite-Klasse automatisch verwendet C # 5.0 Anrufer-Info-Attribute, das schwere Heben zu tun, der obige Code macht streng Kopieren und Einfügen.

Wie ich schon erwähnt, in dem verknüpften SO Q & A, ich bin auf einem Weg arbeiten, dies zu einem Attribute umgewandelt zu bekommen, aber jetzt wird es der Job zu erledigen.

Der Code wird ein Fall für die URL erzwingen. Der Fall wird das gleiche wie der Name der Methode des Controllers - Sie wählen, ob Sie alle Kappen wollen, alle niedriger, oder eine Mischung aus beidem (Camelcase ist gut für URLs). Es wird 301 Umleitungen für Groß- und Kleinschreibung Einstimmungen ausgeben, und speichert die Ergebnisse im Speicher für die beste Leistung. Es wird auch umleiten Schrägstriche (erzwungen für Indexlisten, erzwungen aus anderen Gründen) und entfernen Sie doppelte Inhalte zugegriffen über den Standard-Methode Namen (Index in einem Lager ASP.NET MVC-app).

Hinter

Ich weiß wirklich nicht, wie man nach 8 Jahren fühlen, wird aber jetzt ASP MVC 5 unterstützt Attribut Routing für einfache Routen zu erinnern und zu lösen Duplicate Content Probleme für SEO Friendly Websites

nur hinzufügen routes.MapMvcAttributeRoutes (); in Ihrem RouteConfig und definiert dann einen und einzigen Weg für jede Aktion wie

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

auf die Antwort Basierend von Gabe Sumner, aber ohne Umleitungen für JS, Bilder und andere Inhalte. Funktioniert nur auf Controller-Aktionen. Die Idee ist, die Umleitung später in der Pipeline zu tun, wenn wir wissen, dass sein bereits eine Route. Dafür können wir einen Actionfilter verwenden.

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

Beachten Sie, dass die Filter nicht weitergeleitet umleiten oder das Gehäuse für den Query-String ändern.

binden dann die Action global für alle Aktionen, indem sie es auf die GlobalFilterCollection hinzuzufügen.

filters.Add(new RedirectFilterAttribute());

Es ist eine gute Idee, immer noch die LowercaseUrls Eigenschaft auf true gesetzt Routecollection.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top