بهینه سازی برنامه‌های وب ASP.NET برای موتورهای جستجو (SEO)
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: پنج دقیقه

می‌دانیم بهینه‌سازی موتورهای جستجو (به انگلیسی: ‎Search engine optimization (SEO)‎)‏ که گاهی در فارسی به آن سئو نیز گفته می‌شود، عملیاتی است برای بهبود دید یک وب‌گاه یا یک صفحهٔ وب، در صفحه نتایج موتورهای جستجو که می‌تواند طبیعی و یا الگوریتمی باشد. این عملیات برای وبمسترها یکی از عوامل مهم و حیاتی بدست آوردن کاربران جدید از موتورهای جستجو است.

اگر چک لیست‌های SEO وب سایت ها را مشاهده کنیم، می‌توانیم آن‌ها را در دو دسته‌ی کلی بهینه سازی درونی و برونی وب سایت در نظر بگیریم:
Off-Page Optimization
یا برونی ، که بیشتر بر دوش مشاوران سئو و خود مدیران وب سایت است.(link building ، فعالیت در شبکه اجتماعی و ...)
و اما در حوزه On-Page Optimization یا درونی که بخش‌های مهمی از آن وظیفه‌ی مابرنامه نویس‌ها است.(H1 Tag ، URL Naming ، Meta Tags ، عنوان صفحه و ...)
[البته عامل درونی بهینه سازی محتوا (Content Optimization)  که مهمترین عامل در الگوریتم‌های نسل جدید موتورهای جستجو و همچنین الگوریتم جدید گوگل+) به حساب می‌آید بر عهده مشاوران سئو و خود مدیران وب سایت می‌باشد]


در ادامه به ارائه چند راهکار جهت بهینه سازی برنامه‌های وب ASP.NET مان برای موتورهای جستجو می‌پردازیم:


1.متدی برای ایجاد عنوان سایت
    private const string SeparatorTitle = " - ";
    private const int MaxLenghtTitle = 60;
    public static string GeneratePageTitle(params string[] crumbs)
    {
        var title = "";

        for (int i = 0; i < crumbs.Length; i++)
        {
            title += string.Format
                        (
                            "{0}{1}",
                            crumbs[i],
                            (i < crumbs.Length - 1) ? SeparatorTitle : string.Empty
                        );
        }

        title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim();

        return title;
    }
نکته :
  • MaxLenghtTitle پیشنهادی برای عنوان سایت 60 می‌باشد.

2.متدی برای ایجاد متاتگ صفحات سایت
public enum CacheControlType
{
    [Description("public")]
    _public,
    [Description("private")]
    _private,
    [Description("no-cache")]
    _nocache,
    [Description("no-store")]
    _nostore
}  
private const int MaxLenghtTitle = 60; private const int MaxLenghtDescription = 170; private const string FaviconPath = "~/cdn/ui/favicon.ico"; public static string GenerateMetaTag(string title, string description, bool allowIndexPage, bool allowFollowLinks, string author = "", string lastmodified = "", string expires = "never", string language = "fa", CacheControlType cacheControlType = CacheControlType._private) { title = title.Substring(0, title.Length <= MaxLenghtTitle ? title.Length : MaxLenghtTitle).Trim(); description = description.Substring(0, description.Length <= MaxLenghtDescription ? description.Length : MaxLenghtDescription).Trim(); var meta = ""; meta += string.Format("<title>{0}</title>\n", title); meta += string.Format("<link rel=\"shortcut icon\" href=\"{0}\"/>\n", FaviconPath); meta += string.Format("<meta http-equiv=\"content-language\" content=\"{0}\"/>\n", language); meta += string.Format("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"/>\n"); meta += string.Format("<meta charset=\"utf-8\"/>\n"); meta += string.Format("<meta name=\"description\" content=\"{0}\"/>\n", description); meta += string.Format("<meta http-equiv=\"Cache-control\" content=\"{0}\"/>\n", EnumExtensions.EnumHelper<CacheControlType>.GetEnumDescription(cacheControlType.ToString())); meta += string.Format("<meta name=\"robots\" content=\"{0}, {1}\" />\n", allowIndexPage ? "index" : "noindex", allowFollowLinks ? "follow" : "nofollow"); meta += string.Format("<meta name=\"expires\" content=\"{0}\"/>\n", expires); if (!string.IsNullOrEmpty(lastmodified)) meta += string.Format("<meta name=\"last-modified\" content=\"{0}\"/>\n", lastmodified); if (!string.IsNullOrEmpty(author)) meta += string.Format("<meta name=\"author\" content=\"{0}\"/>\n", author); //------------------------------------Google & Bing Doesn't Use Meta Keywords ... //meta += string.Format("<meta name=\"keywords\" content=\"{0}\"/>\n", keywords); return meta; }
چند نکته :

3.متدی برای ایجاد Slug ( اسلاگ آدرسی با مفهوم برای بکار بردن در URL ها است که دوست‌دار موتورهای جستجو می‌باشد)
private const int MaxLenghtSlug = 45;
public static string GenerateSlug(string title)
{
        var slug = RemoveAccent(title).ToLower();
        slug = Regex.Replace(slug, @"[^a-z0-9-\u0600-\u06FF]", "-");
        slug = Regex.Replace(slug, @"\s+", "-").Trim();
        slug = Regex.Replace(slug, @"-+", "-");
        slug = slug.Substring(0, slug.Length <= MaxLenghtSlug ? slug.Length : MaxLenghtSlug).Trim();

        return slug;
}
    
private static string RemoveAccent(string text)
{
        var bytes = Encoding.GetEncoding("UTF-8").GetBytes(text);
        return Encoding.UTF8.GetString(bytes);
}
نکته :
  • MaxLenghtSlug پیشنهادی برای عنوان سایت 45 می‌باشد. 

نمونه ای از کاربرد توابع :
   Head.InnerHtml = SEO.GenerateMetaTag
                            (
                                title: SEO.GeneratePageTitle(".NET Tips", "آرشیو مطالب", "ASP.NET MVC #1"),
                                description: "چرا ASP.NET MVC با وجود فریم ورک پخته‌ای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح می‌شود این است: «برای چی؟». بنابراین تا به این سؤال پاسخ داده نشود، هر نوع بحث فنی در این مورد بی فایده است.",
                                allowIndexPage: true,
                                allowFollowLinks: true,
                                author: "وحید نصیری",
                                cacheControlType: SEO.CacheControlType._private
                            );
و خروجی در Page Source :
<title>.NET Tips - آرشیو مطالب - ASP.NET MVC #1</title>
<link rel="shortcut icon" href="../../cdn/images/ui/favicon.ico"/>
<meta http-equiv="content-language" content="fa"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta charset="utf-8"/>
<meta name="description" content="چرا ASP.NET MVC ؟با وجود فریم ورک پخته‌ای به نام ASP.NET web forms، اولین سؤالی که حین سوئیچ به ASP.NET MVC مطرح می‌شود این است: &#171;برای چی؟&#187;. بن ..."/>
<meta http-equiv="Cache-control" content="private"/>
<meta name="robots" content="index, follow" />
<meta name="expires" content="never"/>
<meta name="author" content="وحید نصیری"/>
موفق باشید
  • #
    ‫۱۰ سال و ۱۰ ماه قبل، جمعه ۸ آذر ۱۳۹۲، ساعت ۱۸:۵۰
    دوست من با این روش
    Head.InnerHtml = SEO.GenerateMetaTag(....)
    در صورتی که در قسمت head صفحه استایل یا متاتگهای دیگری تعریف شده باشد همگی حذف خواهند شد.

    • #
      ‫۱۰ سال و ۱۰ ماه قبل، جمعه ۸ آذر ۱۳۹۲، ساعت ۲۲:۱۵
      بله صابر جان حتما همین طور است (برای مثال بیان شده است).
      خودم به این صورت استفاده می‌کنم :
      <head>
          <asp:Literal runat="server" ID="litHead"></asp:Literal>
      ....
      </head>
      و در قسمت code-behind
      litHead.Text = SEO.GenerateMetaTag(...)
      پ ن : چرا از کنترل Literal استفاده شده و از Label استفاده نشده ؟ به این دلیل که خروجی متن رندر شده Label توسط تگ <span> یا <label> احاطه می‌شود. (+)
  • #
    ‫۱۰ سال و ۹ ماه قبل، شنبه ۱۴ دی ۱۳۹۲، ساعت ۱۵:۴۵
    با سلام
    امکان داره این خط کلاسش رو هم بزارید بنده دقیقا نتونستم با متد الحاقی که گفتین این قسمت رو پیاده سازی کنم
    EnumExtensions.EnumHelper<CacheControlType>.GetEnumDescription(cacheControlType.ToString()));
  • #
    ‫۱۰ سال و ۹ ماه قبل، شنبه ۱۴ دی ۱۳۹۲، ساعت ۱۶:۵۸
    بنده یه مشکلی دارم : از MasterPage استفاده می‌کنم در ASP.net Webform و فرمی رو بهش Connect کردم که:
    1- در MPage یک سری متا تگ‌ها هست + CSS + JavaScript
    2- وقتی در یک webForm متصل به Mpage کد:

    Head.InnerHtml = SEO.GenerateMetaTag ....

    رو قرار می‌دهم تمام تگ‌های Head حتی MasterPage هم پاک می‌شه
    اینم می‌دونم این کلاس این کارو می‌کنه
    راه حل چیه که تگ‌ها پاک نشه ؟ مخصوصا آدرس‌های CSS و JavaScript ؟
  • #
    ‫۱۰ سال و ۸ ماه قبل، چهارشنبه ۲ بهمن ۱۳۹۲، ساعت ۱۹:۴۶
    من این توابع را خواندم که در مورد seo نوشته بودید ولی متاسفانه نحوه استفاده از آن هارا نفهمیدم یعنی کجا تعریف میشن و از کجا پارامتر‌های خود را دریافت می‌کنند. لطف کنید اگر امکان داره یه پروژه کوچک همه این‌ها استفاده شده باشه اگر هست بگذارید .
    نکته دیگه شما عنوان هر پست را داخل url‌ها نمایش میدهید منظور اینکه جزئی از url سایت است این کار را چگونه انجام می‌دهید 
    mysite.info/post/1
    dotnettips.info/post/1200/seo
    • #
      ‫۱۰ سال و ۸ ماه قبل، چهارشنبه ۲ بهمن ۱۳۹۲، ساعت ۲۰:۰۸

      - پروژه Iris هست. به section metatags اون دقت کن در فایل‌های View.

      - مثلا متد Head.InnerHtml = SEO.GenerateMetaTag عنوان شده در این مطلب باید در Page_Load یک وب فرم فراخوانی شود. Id مطلب رو دارید. عنوان و متن و سایر مشخصات اون رو از دیتابیس دریافت کنید و بعد فقط یک جایگذاری است در متد تهیه شده.

      - به اینکار Routing و Url rewrite می‌گن. بحثش در MVC و وب فرم‌ها کمی با هم فرق می‌کنه.

  • #
    ‫۱۰ سال و ۲ ماه قبل، پنجشنبه ۹ مرداد ۱۳۹۳، ساعت ۰۸:۰۵
    لطفا مثالی را در مورد نحوه‌ی استفاده از "متدی برای ایجاد Slug  " در عمل ارسال نمائید. با تشکر
    • #
      ‫۹ سال و ۹ ماه قبل، شنبه ۲۲ آذر ۱۳۹۳، ساعت ۲۱:۳۹
      سلام منم کد‌ها رو تویه فایل csبه نام سئو دخیره کردم اما اینجا وقتی ران میکنم ارور میده
      public enum CacheControlType
      {
          [Description("public")]
          _public,
          [Description("private")]
          _private,
          [Description("no-cache")]
          _nocache,
          [Description("no-store")]
          _nostore
      }
      • #
        ‫۹ سال و ۹ ماه قبل، شنبه ۲۲ آذر ۱۳۹۳، ساعت ۲۲:۳۵
        «ارور می‌ده» برای رفع مشکل کافی نیست. چه خطایی می‌ده دقیقا؟
        • #
          ‫۹ سال و ۹ ماه قبل، یکشنبه ۲۳ آذر ۱۳۹۳، ساعت ۱۲:۱۰
          درسته حق با شماست. این ارور هست؛ یه نگاهی بندازین فکر کنم با فرم وورکم مشکل داره؟
              Attribute 'Description' is not valid on this declaration type. It is only valid on 'method' declarations.
          • #
            ‫۹ سال و ۹ ماه قبل، یکشنبه ۲۳ آذر ۱۳۹۳، ساعت ۱۲:۵۹
            - ابتدا باید اسمبلی استاندارد System.ComponentModel.DataAnnotations به ارجاعات پروژه اضافه شود.
            - سپس باید از فضای نام مرتبط استفاده کنید (و نه از فضاهای نام مشابه)
            enum MyEnum {
                [System.ComponentModel.Description("Blah")]
                MyValue
            }
            • #
              ‫۹ سال و ۹ ماه قبل، یکشنبه ۲۳ آذر ۱۳۹۳، ساعت ۱۹:۲۸
              بازم تشکر بله مشکل همین بود و طبق دستور شما استفاده کردم و در headهم از یه لیترال استفاده کردم وخیلی خوب جواب داد.زنده باشین
  • #
    ‫۹ سال و ۷ ماه قبل، یکشنبه ۳ اسفند ۱۳۹۳، ساعت ۱۵:۲۹
    سلام.
    هنگام جستجو در گوگل گاهی اوقات سایتی باز میشه که خود اون سایت هم کلمه کلیدی شما رو جستجو کرده و نتایج رو به شما نشون میده.
    مثلا یک فروشگاه خوب هنگامی که در گوگل قیمت رم لپ تاپ رو جستجو کنید چنین صفحه ای داره.
    به نظر شما دوستان چطور میشه چنین صفحه ای در سایت خود داشته باشیم؟
    • #
      ‫۹ سال و ۷ ماه قبل، یکشنبه ۳ اسفند ۱۳۹۳، ساعت ۱۸:۳۷
      - ابتدا یک پروفایل Google analytics ایجاد کنید و سپس اسکریپت آن‌‌را به سایت خودتان اضافه کنید.
      - چند روز بعد که به آمار آن مراجعه کنید، می‌توانید لیست جستجوهای گوگل منتهی به سایت خودتان را به همراه واژه‌های کلیدی مرتبط، گزارش گیری کنید.


      - بر اساس این واژه‌های کلیدی، برای محصولات خودتان برچسب درست کنید یا آن‌ها را گروه بندی کنید. گوگل بر این اساس در دفعات آتی، نتایج جستجوی دقیق‌تری را به کاربران ارائه می‌دهد.
      • #
        ‫۹ سال و ۷ ماه قبل، یکشنبه ۳ اسفند ۱۳۹۳، ساعت ۱۸:۵۵
        پیرو تکمیل صحبت آقای نصیری،
        احتمالا جستجو در وب سایت مورد نظر در دو صفحه مجزا طراحی شده :
        1.جستجوی‌های طبقه بندی شده بر اساس اطلاعات استخراجی شان از ابزار‌ها ارزیابی وب سایت‌ها مانند Google analytics (راهنما در کامنت قبل)
        2. جستجوی لحظه ای در محتوای سایت 
        این نکته در متا تگ‌های ایجاد شده نیز قابل مشاهده است :

        تعداد نتایج یافت شده متفاوت این دو صفحه (با یک عنوان جستجو) نشان از تایید مطلب دارد.

        • #
          ‫۹ سال و ۷ ماه قبل، سه‌شنبه ۱۹ اسفند ۱۳۹۳، ساعت ۲۰:۲۱
          بر فرض مثال ما می‌خواهیم زمانی که از گوگل شخصی به سایت ما هدایت می‌شود با کلمه کلیدی ای که وارد سایت شده به طور خودکار در سایت جستجو کنیم.
          کلا چطور میشه متوجه شد که کاربری از گوگل به سایت ما وارد شده و با چه جستجویی؟
          • #
            ‫۹ سال و ۷ ماه قبل، سه‌شنبه ۱۹ اسفند ۱۳۹۳، ساعت ۲۲:۴۴
            Request.UrlReferrer را آنالیز کنید. مقدار آن مشخص می‌کند که مثلا شخص از گوگل است یا سایت‌های جستجوی دیگر. بعد بر این اساس، کوئری استرینگ q آن‌را یافته و سپس شخص را به صفحه‌ی جستجو هدایت کنید:
            // for Google
            var urlReferrer = Request.UrlReferrer.ToString();
            var query = HttpUtility.ParseQueryString(urlReferrer);
            var searchQuery = query["q"];
            یک نمونه‌ی کاملتر
            • #
              ‫۹ سال و ۶ ماه قبل، چهارشنبه ۲۰ اسفند ۱۳۹۳، ساعت ۲۳:۵۹
              یک سوال داشتم
              اینکه این گونه سایت‌ها از این روش برای افزایش بازدید استفاده می‌کنند یک نوع کلاه برداری در SEO به شمار نمیاد؟
              چون که عموما این سایت‌ها هیچ محتوای مرتبطی ندارن و به خاطر افزایش بازدید اینکارو می‌کنن و باعث به هم ریختن نتایج جست و جو میشن تا جایی که گاهی اوقات می‌بینی چند صفحه اول تمام لینک‌ها از این قبیل سایت هاست و گوگل هم بارها هشدار داده سایت هایی که کلاه برداری می‌کنند و محتوا ندارن رو جریمه می‌کنه ولی به تا به حال یک بار هم این حرف عملی نشده و همچنان همان سایت‌ها هم به فعالیت ادامه میدن و باعث به هم ریختگی میشن
              • #
                ‫۹ سال و ۶ ماه قبل، پنجشنبه ۲۱ اسفند ۱۳۹۳، ساعت ۱۳:۲۶
                هرکسی از ظن خود شد یار من ...