كيف يمكنني تجنب المحتوى المكرر في ASP.NET MVC بسبب عناوين URL والإعدادات الافتراضية غير الحساسة لحالة الأحرف؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

يحرر:الآن أحتاج إلى حل هذه المشكلة بشكل حقيقي ، لقد قمت بمزيد من التحقيق وتوصلت إلى عدد من الأشياء لتقليل المحتوى المكررة.لقد نشرت عينات رمز مفصلة على مدونتي: تقليل محتوى مكرر مع ASP.NET MVC

المشاركة الأولى - كن هادئًا إذا قمت بتمييز هذا الأمر بشكل خاطئ أو قمت بوضع علامة عليه بشكل سيء :P

في إطار عمل ASP.NET MVC الجديد من Microsoft، يبدو أن هناك شيئان يمكن أن يتسببا في عرض المحتوى الخاص بك على عناوين URL متعددة (وهو أمر يعاقب عليه Google وسيتسبب في تقسيم نظام تصنيف الصفحات الخاص بك عبرها):

  • عناوين URL غير حساسة لحالة الأحرف
  • عنوان URL الافتراضي

يمكنك تعيين وحدة التحكم/الإجراء الافتراضي لتقديم الطلبات إلى جذر المجال الخاص بك.لنفترض أننا اخترنا HomeController/Index.ننتهي بعناوين URL التالية التي تقدم نفس المحتوى:

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

الآن، إذا بدأ الأشخاص في الارتباط بكل منهما، فسيتم تقسيم نظام ترتيب الصفحات.ستعتبر Google أيضًا أنه محتوى مكرر وتعاقب أحدهم لتجنب التكرارات في نتائجها.

علاوة على ذلك، فإن عناوين URL ليست حساسة لحالة الأحرف، لذلك نحصل في الواقع على نفس المحتوى لعناوين URL هذه أيضًا:

  • mydomain.com/Home/Index
  • mydomain.com/home/index
  • mydomain.com/Home/index
  • mydomain.com/home/Index
  • (والقائمة تطول)

إذن السؤال...كيف أتجنب هذه العقوبات؟أود:

  • جميع طلبات إعادة توجيه الإجراء الافتراضي (الحالة 301) إلى نفس عنوان url
  • يجب أن تكون جميع عناوين URL حساسة لحالة الأحرف

ممكن؟

هل كانت مفيدة؟

المحلول

صدم!

إم في سي 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/

أميل إلى إنتاج عناوين 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 الأساسي الخاص بالإجراء الخاص بك إذا كان عنوان URL للطلب الحالي لا يتطابق معه.

نصائح أخرى

كنت أعمل على هذا أيضا.من الواضح أنني سأرجع إلى 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();
    }
}

سؤال عظيم!

بالإضافة إلى النشر هنا، قمت بإرسال بريد إلكتروني إلى 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 للمطابقة.

أعتقد أن هناك إجابة أفضل لهذا.إذا وضعت رابطًا أساسيًا في رأس صفحتك مثل:

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

بعد ذلك، يعرض Google الصفحة الأساسية فقط في نتائجها، والأهم من ذلك، أن كل مزايا Google تذهب إلى تلك الصفحة دون أي عقوبة.

مثلك، لدي نفس السؤال;باستثناء أنني لم أكن أرغب في قبول قيود عنوان URL التي تحتوي على أحرف صغيرة بالكامل، ولم يعجبني canonical نهج إما (حسنا، انها جيدة ولكن ليس من تلقاء نفسها).

لم أتمكن من إيجاد حل، لذلك نحن مكتوبة ومفتوحة المصدر أ إعادة توجيه الطبقة.

استخدامه سهل بما فيه الكفاية:تحتاج كل طريقة GET في فئات وحدة التحكم إلى إضافة هذا السطر فقط في البداية:

Seo.SeoRedirect(this);

تستخدم فئة إعادة كتابة تحسين محركات البحث (SEO) تلقائيًا سمات معلومات المتصل الخاصة بـ C# 5.0 للقيام بالمهمة الثقيلة، مما يجعل الكود أعلاه قابلاً للنسخ واللصق بشكل صارم.

كما ذكرت في SO Q&A المرتبط، أنا أعمل على طريقة لتحويل هذا إلى سمة، ولكن في الوقت الحالي، يتم إنجاز المهمة.

سيفرض الرمز حالة واحدة لعنوان URL.ستكون حالة الأحرف هي نفس اسم طريقة وحدة التحكم - يمكنك اختيار ما إذا كنت تريد استخدام الأحرف الكبيرة كلها، أو جميعها أقل، أو مزيجًا من الاثنين معًا (يُعد CamelCase مناسبًا لعناوين URL).سيتم إصدار عمليات إعادة توجيه 301 للمطابقات غير الحساسة لحالة الأحرف، وتخزين النتائج مؤقتًا في الذاكرة للحصول على أفضل أداء.كما أنه سيعيد توجيه الخطوط المائلة العكسية اللاحقة (التي يتم فرضها على قوائم الفهرس، ويتم فرضها بطريقة أخرى) وإزالة المحتوى المكرر الذي يتم الوصول إليه عبر اسم الطريقة الافتراضية (Index في تطبيق ASP.NET MVC للأسهم).

لا أعرف حقًا كيف ستشعر بعد 8 سنوات ولكن الآن يدعم ASP MVC 5 توجيه السمات لتسهيل تذكر المسارات وحل مشكلات المحتوى المكررة للمواقع الصديقة لكبار المسئولين الاقتصاديين (SEO)

فقط أضف ROUTES.MAPMVCATTRIBUTHEROUTES () ؛في 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());

إنها فكرة جيدة أن تستمر في تعيين الخاصية LowercaseUrls على القيمة true في RouteCollection.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top