در کنار سایت های وردپرسی، بسیاری از سایت های دیگر وجود دارند که هر کدام برای بهینه شدن نیاز به طی کردن مراحل خاصی دارند. به طور کلی تمامی سایت ها باید در سه بخش بهینه شوند:
- در بخش محتوا
- در بخش نامک (URL)
- و در بخش ایندکس شدن
به همین ترتیب در این مطلب قصد داریم تا شما را با نحوه سئو کردن سایت های MVC ASP.NET آشنا کنیم.
اگرچه قابلیت های ذاتی سایت های تحت ASP.NET MVC آن ها را قادر ساخته تا همانند سایت های وردپرسی خود را در موتورهای جستجو (SEO) بهینه کنند، اما هنوز تعداد زیادی از مشکلات وجود دارد که سایت های IIS و ASP.NET در صورت عدم بررسی می توانند از بین بروند.
آموزش سئو ASP.NET MVC
همانند سایت های وردپرسی باید به موضوع آموزش سئو سایت های ASP.NET MVC نیز اهمیت دهیم. در گام اول باید اقدام به تولید محتوا و بررسی کلمات کلیدی کرد.
برای این کار می توان لیستی از کلمات کلیدی را توسط ابزارهای مختلق پیدا کرد و آنها را به صورت پراکنده در متن قرار داد.
خب اکنون که کلمات کلیدی را پیدا کردید، وقت آن رسیده تا یک محتوای با کیفیت تولید کنیم. اما در اینجا یک نکته اساسی وجود دارد. تا اینجای کار را یادتان بماند تا به یک نکته مهم اشاره کنیم. سپس برمی گردیم سر نحوه نوشتن محتوا.
یک نکته اساسی که بسیاری از موتورهای جستجو در تلاشند تا آن را به سرانجام برسانند، کاهش مقدار محتوای تکراری در بستر گوگل است. در برخی از مواقع اگر توجه کرده باشید، پس از سرچ کردن موضوعات خود، گوگل در قسمت پایین صفحه اشاره به حذف شدن برخی صفحات کرده است. این صفحات در واقع همان صفحات کپی و تکراری هستند که در هنگام اجرای یک جستجو در مرورگر نشان داده می شوند.
از قضا، سایت های IIS و ASP.NET به راحتی و به طور پیش فرض محتوای تکراری ایجاد می کنند - فقط به این دلیل که سایت های IIS و ASP.NET برای اطمینان از اینکه بازدیدکنندگان به محتوای درخواستی خود دست یابند، اقدام به تولید چند سری کپی از محتوای تولید شده می کنند.
به عنوان مثال، اگر شما نشانیهای اینترنتی زیر را برای یک صفحه ساده در یک وب سایت در نظر بگیرید، هر کدام از URL ها کار خواهند کرد (تحت شرایط پیشفرض)؛ در واقع این همان چیزی است که در بالا به آن اشاره کردیم:
"تلاش حداکثری سایت های IIS و ASP.NET برای بالا آوردن مطالب"
• http://www.poonehmedia.com/categories/
• http:// poonehmedia.com/categories/
• http:// poonehmedia.com/categories
• http:// poonehmedia.com/categories/default.aspx
• http:// poonehmedia.com/Categories/
مشکل این است که همه این URL ها متفاوت و منحصر به فرد هستند - به این معنی که سایتی که دسترسی به محتوای یکسان را از طریق همه این URL ها فراهم می کند در واقع مقصر ایجاد محتوای تکراری است. و از آنجا که موتورهای جستجو به دنبال حذف محتوای تکراری هستند، وجود این مشکل می تواند رتبه بندی صفحات را کاهش دهد؛ تا جایی که این مسئله در محافل جستجوگرها (گوگل، یاهو، Bing، فایرفاکس و ...) از اهمت بالایی برخوردار شده است. تنها راه حل برای رفع این مشکل یکی کردن این پیوندها است که برای محتوای سایت شما ایجاد شده اند.
رفع مشکل
مساله اصلی البته این است که اگر سایت پرمحتوایی دارید، استاندارد کردن پیوندها کار دشواری است. علاوه بر این، یک مشکل بزرگتر این است که شما کنترل زیادی بر روی بک لینک هایی که سایت های خارجی به محتوای شما می دهند، ندارید و از قضا موتورهای جستجو تاکید زیادی بر هدایت پیوندهای خارجی دارند.
در نتیجه، مواردی مانند وجود یا عدم وجود مضرابهای انتهایی، حروف بزرگ و استفاده یا عدم استفاده از "www" در نهایت مشکلاتی هستند که هنگام رسیدگی به درخواست ها باید آنها را رفع کنید. در واقع سایت های IIS و ASP.NET این واقعیت را پذیرفته اند که استفاده از URL ها از یک کاربر به کاربر دیگر بسیار متفاوت است.
این سایت ها نامک های کپی را از دید توسعه دهندگان خود محو می کنند، اما ممکن است نتوانند آنها را از نظر برخی کاربران و حتی موتورهای جستجو مخفی کنند.
یک روش ابتدایی برای رفع همه این نگرانی ها استفاده از یک فیلتر اکشن ساده است که با ارسال کد HTTP 301 (که بطور موثر توسط کاربران قابل مشاهده نیست، اما به ربات ها دقیقا URL مورد نظر را نشان می دهد) نامک ها را استانداردسازی می کند. درست است که تمامی URL ها وجود دارند، اما تنها یکی از آنها برای موتورهای جستجو تعریف می شود.
ایجاد اکشن canonicalization
ایجاد فیلتر اکشن canonicalization برای اپلیکیشن های MVC در واقع یک روش پیش پا افتاده و قدیی است. اما چاره ای نیست! تنها چیزی که نیاز دارید گردآوری یک سری مجموعه قوانین استاندارد است که می خواهید برای دسترسی به محتوای سایت خود آن را تعریف کنید و سپس برای اجرای این قوانین باید چند کد ساده را در ASP.NET بنویسید. سپس این فیلتر را به تمام کنترلکنندهها (یا به کنترلکننده پایه) اعمال کنید، تا اطمینان حاصل شود که تمام کنترلکنندههای دیگر شما نیز به طور مداوم به sitewide دسترسی دارند.
به عنوان مثال در فیگور زیر، شما می توانید همیشه در URL ها "www" را به عنوان بخشی از نامک خود به میزبان ارجاع دهید. یا این که پیوندها باید همیشه با حروف کوچک باشند و با یک اسلش (/) در انتهای خود خاتمه یابند.
public class CanonicalizedAttribute : ActionFilterAttribute
{
private IAppConfiguration _config;
public CanonicalizedAttribute()
{
this._config = DependencyResolver.Current.GetService<IAppConfiguration>();
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContextBase Context = filterContext.HttpContext;
string path = Context.Request.Url.AbsolutePath ?? "/";
string query = Context.Request.Url.Query;
// don't 'rewrite' POST requests or you'll lost values:
if (Context.Request.RequestType == "GET")
{
// check for any upper-case letters:
if (path != path.ToLower(CultureInfo.InvariantCulture))
{
this.Redirect(Context, path, query);
return;
}
// make sure request ends with a "/"
if(!path.EndsWith("/"))
{
this.Redirect(Context, path + "/", query);
return;
}
// perform hostname checks (unless working in dev):
if (this._config.IsProductionServer)
{
string hostName =
Context.Request.Url.Host.ToLower(CultureInfo.InvariantCulture);
if (!hostName.Contains("sqlservervideos.com"))
{
this.Redirect(Context, path, query);
return;
}
// don't allow host-name only connections (i.e., force 'www'):
if (!hostName.StartsWith("www."))
{
this.Redirect(Context, path, query);
return;
}
}
}
base.OnActionExecuting(filterContext);
}
// correct as many 'rules' as possible per redirect to avoid
// issuing too many redirects per request.
private void Redirect(HttpContextBase context, string path, string query)
{
string newLocation = "http://www.sqlservervideos.com" + path;
if (!newLocation.EndsWith("/"))
newLocation += "/";
newLocation = newLocation.ToLower(CultureInfo.InvariantCulture);
context.Response.RedirectPermanent(newLocation + query, true);
}
}
اگر به کد فیلتر فوق نگاه کنید، می بینید که منطق خاصی در آن به کار نرفته و بهتر است بگوییم منطق اهمیتی در آن ندارد. تمام کاری که سئوکار در این کد انجام داده این است که روش OnExecuting فیلتر را نادیده گرفته تا بررسی های بسیار ساده ای انجام دهد؛ به این خاطر که اطمینان حاصل شود تا درخواست ها با قوانینی که ترجیحا تعریف شده اند، مطابقت داشته باشد.
به عنوان مثال، کدنویس در دو بررسی اول اطمینان حاصل کرده است که همه چیز مختصر است و تمام درخواست ها در یک اسلش خاتمه می یابند. با این حال، شما می توانید به راحتی منطق اسلش اسکریپت او را برعکس کنید تا مطمئن شوید که درخواست ها به یک اسلش (/) ختم می شوند یا خیر.
چند نکته مهم
در فیلتر فوق چند نکته وجود دارد که باید به آن توجه شود. یک نکته این است که، کدنویس هنگام پردازش قوانین متعارف سازی فقط برای درخواست های GET تلاش کرده است، و این به دو دلیل است.
اول، موتورهای جستجو (یا ربات های آنها) نباید درخواست های POST (POST requests) را علیه سایت شما اجرا کنند، بنابراین نیازی به استاندارد کردن طرح های URL مورد استفاده برای عملیات POST نیست.
دوم، وقتی صحبت از عملیات POST می شود، تنها چیزی که همه کدنویسان می خواهند این است که مجموعه داده های فرم POST به طرز مرموزی از بین برود؛ زیرا در زیر کاور ها (پنهان سازی دادهها) یک ریدایرکت شفاف انجام می شود. به عبارت دیگر، اطمینان حاصل کنید که فقط فعلهایی را که دارای معنا هستند، قانونی می دانید (به عنوان مثال: فعل GET).
توجه داشته باشید که قبل از شروع بررسی نام هاست، برای تعیین اینکه آیا نام میزبان با پیشوند "www" آغاز می شود، سریع کلاس پیکربندی خود را بررسی کنید تا مطمئن شوید که در یک سرور در حال توسعه نیستید. در غیر این صورت، در طی مراحل توسعه و آزمایش ، درخواست های هاست محلی به سایت زنده (توسعه یافته) منتقل می شوند. البته، شما می توانید از چند طریق مختلف این کار را انجام دهید، اما نکته اصلی که باید به آن توجه کنید این است که اگر فیلتر canonicalization خود را سفارشی سازی کردید، باید تمام مراحل را خودتان طی کنید.
اگر چه این روش کمی برای شما قابل اطمینان نیست، اما استفاده از روش Redirect می تواند بسیاری از مشکلات canonicalization برای یک درخواست واحد را برطرف کند. زیرا بسیاری از 301 ها میتوانند به رتبهبندی آسیب برسانند. بر این اساس، روش Redirect انتخاب از بین بد و بدتر است.
نتیجه این که...
سایت های ASP.NET MVC به راحتی در معرض ایجاد محتوای تکراری هستند. این در حالی است که اکشن فیلترها پرداختن به این مشکلات را بسیار بی اهمیت می دانند. در عوض، نکته اصلی این است که Action Filters می تواند برای تعریف مجموعه ای از قوانین استفاده شود. در واقع این ابزار به عنوان ابزاری برای بهبود سئوی کلی مورد استفاده قرار می گیرد.
سئو محتوا در ASP.NET
اکنون که به طور مفصل با مشکل تکراری شدن یو آر ال در سایت های ASP.NET آشنا شدید، وقت آن رسیده تا با خیال راحت محتوای خود را تولید کنید.
چیزی که اهمیت ویژه ای در تولید محتوا دارد، کیفیت است. کیفیت حرف اول را برای مخاطبان می زند. موتورهای جستجو نیز تاکید ویژه ای بر روی این موضوع دارند؛ به طوری که شرکت گوگل بارها اعلام کرده است که محتوانویسان فقط به فکر کیفیت محتوا باشند و فقط در انتها به برخی از مهمترین فاکتورهای سئو نیز توجه کنند.
اینگونه نباشد که مانند سال 2000 فقط برای ربات های گوگل مطلب بنویسید. در آن زمان اگر کلمات کلیدی را به طور پی در پی تکرار می کردیم، مطلب سئو می شد و خزنده های گوگل خیلی زود محتوای ما را پیدا می کردند.
محتوای با کیفیت در طولانی مدت تاثیر خود را می گذارد و مخاطبان به مطالب سایت شما اعتماد می کنند. اما اگر می خواهید که این اتفاق زود بیافتد می توانید از روش های زیر استفاده کنید.
انتخاب عناوین جذاب
انتخاب یک عنوان جذاب می تواند کمک زیادی به افزایش ترافیک سایت کند. عنوان دقیقا مانند سردر یک فروشگاه است. فرض کنید دارای یک مغازه مشاور املاک حرفه ای هستید؛ اما فاقد یک بنر یا تابلو برای معرفی مغازه خود هستید. مردم چگونه باید بفهمند که مغازه شما با چند میز و صندلی در چه حوزه ای فعالیت می کند؟
عنوان محتوا نیز دقیقا همین ویژگی را دارد. عنوان اصلی در بخش <title> واقع در <head> قرار می گیرد. در اصل موتورهای جستجو، مطالب سایت را از طریق این عناوین پیدا کرده و برای مخاطبان به نمایش می گذارند.
سعی کنید هیچوقت عنوان سایت را تغییر ندهید؛ این کار باعث می شود تا ضربه ای سختی به سئوی محتوای شما وارد شود. استفاده از کلمه کلیدی کانونی در عنوان بسیار حائز اهمیت است. اینگونه شما به خزنده های گوگل می فهمانید که موضوع اصلی محتوا چیست. البته به شرطی که از کلمه کلیدی کانونی به صورت درست و پراکنده در محتوای خود استفاده کرده باشید.
سعی کنید تنها یکبار از کلمه کلیدی در عنوان خود استفاده کنید. عنوان اصلی معمولا باید تگ H1 باشد. شما در هر محتوا تنها مجاز به استفاده از یک تگ H1 هستید. در غیر این صورت موتورهای جستجو به دلیل سئوی کلاه سیاه شما را جریمه خواهند کرد.
بهتر است عناوین را در 75 کاراکتر بنویسید. چراکه تعداد کاراکترهای بیشتر در نتایج جستجو نمایش داده نمی شوند.
همچنین یادآور می شود برای دستیابی به سئو و رتبه بندی خوب، یک یا دو کلمه کلیدی یا ترکیبی از کلمات کلیدی را انتخاب کنید.
هنگام کار با صفحات اصلی ، یک روش آسان برای درج عنوان وجود دارد:
//assuming, that your <head runat="server" id="myHead">
if (Request.CurrentExecutionFilePath.Contains("example.aspx"))
{
HtmlTitle title = new HtmlTitle();
title.Text = "Example";
myHead.Controls.Add(title);
}
استفاده از متا تگ های مناسب در سئو ASP
طبق یک قانون کلی متاتگ ها باید به ترتیب مورد استفاده قرار گیرند. البته ترتیب قرار گیری متاها در محتوا کمی فرق دارد. همانطور که در قسمت قبل گفتیم، تنها یبار امکان استفاده از تگ H1 آن هم برای عنوام اصلی متن مجاز است.
زمانی می توان از تگ های H3،H4 و ... استفاده کرد که حتما از تگ H2 حداقل برای یک بار استفاده کرده باشیم.
حتی المقدور از تگ های H3 به بعد استفاده نکنید. چراکه بهین هسازی سایت را بهم می ریزند و کار را برا خزنده های گوگل سخت می کنند.
نکاتی مهم هنگام عنوان گذاری
اگر با Web Forms قصد درج عنوان دارید، روشهای مختلفی برای تنظیم عنوان صفحه وجود دارد. شما می توانید آن را در HTML صفحه اصلی رمزگذاری کنید، اما انجام این کار باعث می شود که هر صفحه در سایت شما با عنوان مشابه نمایان شود. اگر در هر صفحه عنوان منحصر به فرد و جذاب می خواهید، باید عنوان را در همان صفحه و در بالای آن قرار دهید. اگر عنوان ثابت است ، می توانید آن را در فایل aspx در دستورالعمل @ Page تنظیم کنید:
<%@ Page Title="About my site" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="WebFormsSEO.About" %>
اما اگر می خواهید یک عنوان پویا (dynamic) تنظیم کنید، ممکن است بخواهید از عنوان مقاله یا دستور العمل وبلاگ خود متناسب با محتوای سایت استفاده کنید. برای این کار می توانید از طریق code-behind با تنظیم Page.Title (یا این.Title یا فقط عنوان) اقدام کنید.
روشی که برای تعیین مقدار عنوان در نظر می گیرید به منبع داده ای که برای ساخت عنوان شما استفاده می شود بستگی دارد. در بیشتر مواقع، برای دسترسی به منبع داده کنترل و استفاده از هر مقداری که می خواهید، از کنترلر DataBound یا RowDataBound استفاده کنید. در این بخش هر مسیری را که انتخاب می کنید، باید به ترتیب باشد.
معمولا کدهای سختی که در HTML یک صفحه اصلی قرار می دهید، برای عموم نمایش داده خواهند شد. از این رو، الگوی استاندارد سایت Web Forms با کدگذاری سخت "- My ASP.NET Application" به عنوان بخشی از مقدار <title> از این ویژگی استفاده می کند، اما همچنین اجازه می دهد قسمت اول <title> به صورت پویا تنظیم شود:
<title><%: Page.Title %> - My ASP.NET Application</title>
وقتی یک فایل aspx جدید به اپلیکیشن خود اضافه می کنید، مقدار پیش فرض Title در دستورالعمل صفحه @ در واقع یک رشته خالی است:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
اگر آن را به همین ترتیب رها کنید، دیگر مهم نیست که در کجا مقدار Page.Title را تنظیم خواهید کرد، چراکه به عنوان یک رشته خالی باقی می ماند. بنابراین، اگر بخواهید مقداری را در دستورالعمل @ Page کدگذاری کنید، باید کل عنوان را از آن حذف کنید.
حال اگر این مقدار را به عنوان یک رشته خالی به حال خود رها نکنید، هر چیزی را که در بخشنامه @ Page قرار دهید، با هر چیزی که در کد پشت صفحه تنظیم کنید ، رونویسی می شود. و این به نوبه خود توسط هر چیزی که از روی کد Master Page تنظیم کنید، رونویسی می شود.
الگوی MVC همچنین شامل برخی از تنظیمات پیش فرض برای تهیه مقدار عنصر <title> در صفحه طرح است:
<title>@ViewBag.Title - My ASP.NET Application</title>
شما می توانید مقدار ViewBag.Title را با تنظیم آن در کنترلر مدیریت کنید. همچنین می توانید آن را در صفحه محتوا تنظیم کنید:
@{
ViewBag.Title = "Home Page";
}
این کد مقدار تعیین شده در کنترلر را لغو می کند. توجه داشته باشید، از آنجایی که ViewBag یک چیز پویا است، به جای استفاده از Title به عنوان نام خاص، می توانید به همین راحتی از PageTitle یا هر چیزی که دوست دارید استفاده کنید.
در سئو ASP به متا دسکریپشن ها توجه کنید
متای توضیحات همان جملات کوتاهی هستند که زیر لینک صفحات نمایش داده می شوند تا اطلاعات مختصری به خواننده بدهند. شما می توانید آنها را با استفاده از تگ <meta> در HTML صفحات خود تنظیم کنید:
<meta name=”description” content=”مقدار متا توضیحات” />
در استفاده از متای توضیحات باید چند نکته مهم را در نظر گرفت. این که باید از کلمات کلیدی در آن استفاده کرد و طول آن نباید بیش از 30 کلمه باشد. این کار باعث می شود تا موتورهای جستجو نیز سریع تر محتویات متن را درک کنند.
تصویر بالا نشان می دهد که Google چگونه از متا توضیحات (با رنگ زرد برجسته شده) در نتایج جستجو خود و کسب اطلاعات از محتویات سایت استفاده می کند. البته گوگل همیشه از متای توضیحات استفاده نمی کند؛ بنابراین اگر طول آن بیش از 160 کاراکتر باشد، قطعا از همه آن استفاده نمی کند.
زمانی که شما از متای توضیحات استفاده نکنید، خود گوگل متنی را به عنوان متای توضیحات از دل مطلب بیرون می کشد. ممکن است متای انتخاب شده توسط گوگل خلی مناسب نباشد، از این رو توصیه می شود خود شما دست به کار شوید و یک متای جذاب به همراه کلمه کلیدی بنویسید.
قبل از معرفی نسخه ASP.NET 4، شما می توانستید از ContentPlaceholder و کلاس HtmlMeta برای تنظیم توضیحات متا در یک سایت وب فرم استفاده کنید. اما از زمان معرفی نسخه ASP.NET 4، کلاس Page یک ویژگی برای برای برنامه نویسان ارائه کرد که شامل MetaDescription می شود. به طوری که توسعه دهندگان Web Forms را قادر می سازد تا طول متای توضیحات را خودشان تعیین کنند:
public partial class About : Page
{
protected void Page_Load(object sender, EventArgs e)
{
MetaDescription = “A page that describes what we are about”;
}
}
تمامی توسعه دهندگان MVC می توانند از رویکرد مشابهی برای تنظیم عنوان مورد نظر خود در برگه های Layout و Viewbag برای تعیین طول متای توضیحات استفاده کنند؛
<meta name=”description” content=”@ViewBag.Description”>
در این مثال فیلدی وجود دارد که امکان قرار دادن پاراگراف ابتدایی هر مطلب را به می دهد. همچنین فیلدی دیگر برای نوشتن متای توضیحات در نظر گرفته شده است.
در این بخش اگر متای توضیحات را مشخص نکنیم، پاراگراف اول متن به عنوان متای توضیحات انتخاب می شود.
ViewBag.Description = article.Description != null ? article.Description : article.Introduction;
متاتگ کلمات کلیدی در سئو ASP
طبق آخرین اصلاحات الگوریتم گوگل، استفاده از متاتگ کلمات کلیدی دیگر اهمیت چندانی ندارد. گوگل هر چند سال یکبار اقدام به آپدیت اساسی الگوریتم های موتورهای جستجوی خود می کند.
با این حال هنوز برخی از برنامه نویسان علاقه دارند تا از این فاکتور برای بهینه تر کردن محتوای سایت خود استفاده کنند.
خوشبختانه در ASP.NET 4 نیز ویژگی MetaKeywords برای کلاس Page در معرفی شده است.
protected void Page_Load(object sender, EventArgs e)
{
MetaKeywords = “spam, spam, spam”;
}
اسکیما را در سئو ASP فراموش نکنید
گوگل برای برخی از سایت های پربازدید، تمایز قائل می شود. به طوری که در کنار متای توضیحات از یک سری اطلاعات اضافه نظیر تاریخ انتشار محتوا، نظرسنجی کاربران و تصاویر استفاده می کند. این اطلاعات که اصطلاحا ریچ اسنیپت نام دارند برای محتواهای مختلف به صورت ای خاصی ارائه می شوند.
مثلا هنگام سرچ یک شخصیت معروف اطلاعاتی نظیر سن، مرگ، زمان تولد، قد، همسر، تعداد فرزندان و ... برای کاربر ظاهر می کند.
احتمالا از خود می پرسید که این اطلاعات چگونه به دست گوگل می رسند؟ الگوریتم های گوگل آنقدر باهوش هستند که قادرند این اطلاعات را پس از چندبار بررسی از دل محتوا بیرون بکشند. اما این کار ممکن است مدت ها زمان ببرد و شاید گوگل هرگز سایت شما را این گونه بررسی نکند.
استفاده از اسکیما مارک آپ می تواند فرایند کار را آسان کند. تجربه ثابت کرده است که چنین اطلاعاتی موجب افزایش نرخ کلیک در سایت می شود.
نحوه استفاده از اسکیما مارک آپ بسیار ساده است. کافی است دستورالعمل استفاده از اسکیما مارک آپ را در وبسایت Schema.org مطالعه کنید.
جالب است که این ابزار تنها به دو روش کار می کند. یکی به شکل کدهای HTML و دیگری به زبان Json-Ld . در صورتی که گزینه اول را انتخاب کنید، تمامی داده ها را می توانید در دو فرمت Microdata یا RDFa به ثبت برسانید.
- JSON-LD
Json-Ld توسط جاوا اسکریپت ها به صورت کاملا مجزا شناخته می شوند. در این سیستم کدنویس می تواند اسکیماها را در یک نقطه دلخواه قرار دهد. برای مثال می توانید کد زیر را برای سیستم امتیازدهی استفاده کنید:
:
<script type=”application/ld+json”>
“@@context”: “http://schema.org”,
“@@type”: “TechArticle”,
“headline”: “@Model.Article.Headline”,
“image”: [
“image1.jpg”
],
“datePublished”: “@Model.Article.DateCreated.ToString(“T”),
“description”: “@Model.Article.Description”,
“articleBody”: “@Model.Article.Maintext”,
“aggregateRating”: {
“@@type”: “AggregateRating”,
“ratingValue”: “@Model.ArticleRating.AverageRating”,
“reviewCount”: “@Model.ArticleRating.TotalRaters”
}
</script>
<script type=”application/ld+json”>
“@context”: “http://schema.org”,
“@type”: “TechArticle”,
“headline”: “<%: Model.Article.Headline %>”
- Microdata
در این فرمت برخلاف فرمت قبل می توانید تمام محتوا را نشانه گذاری کنید. این کار از طریق itemcope میسر است. با itemcope امکان تعیین نوع آیتم نیز وجود خواهد داشت. درواقع تعداد کارکتارهای itemtype به شکل پیوندهایی هستند که متناسب با اسکیمای مورد نظر ایجاد می شوند. به عبارت ساده تر مقدار itemtype پیوندی است که به اسکیمای تعیین شده ربط دارد. مطالبی هم که از نوع تکنیکال باشند در یک تگ HTML یا div به مقدار عنوان مشخص می شوند.
برای توصیف آیتم نیز باید از طریق attribute اقدام کرد.
ایجاد URL های دوستانه کاربرپسند در برنامه ASP.NET MVC
برای شروع نگاهی به URL سایت آمازون کنید:
http://www.amazon.com/gp/product/1617292397/ref=s9_psimh_gw_p14_d4_i1?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-1&pf_rd_r=0TFM5Q6WM6KD9NPNG9G7&pf_rd_t=36701&pf_rd_p=2079475242&pf_rd_i=desktop
در نگاه اول چه ایده در ذهن شما خلق شد؟
اما نگاهی به URL زیر کنید:
http://www.dpreview.com/articles/9485436827/the-big-beast-hands-on-with-the-panasonic-lumix-dmc-gx8
نظر شما چیست؟ آیا در نگاه اول توجه شما به تلفن همراه Panasonic Lumix DMX-GX8 جلب نشد؟
همانطور که مشاهده کردید در پیوند نخست هیچ نشانی از محصول خاصی نیست، اما در پیوند دوم به طور واضح از محصول رونمایی شده است. بنابراین، URL کاربرپسند به این معناست که کاربر با دیدن آن بلافاصله با موضوع ارتباط برقرار کند.
درست است که موتورهای جستجوی گوگل بسیار هوشمند هستند و مو را از ماست بیرون می کشند؛ اما آیا این بی انصافی نیست که برای پیوندهای مشابه پیوند نخست ارزش بیشتری قائل شوند؟ در صورتی که پیوند دوم خیلی بهینه و کاربرپسندتر است؟
روش های مختلفی برای ایجاد URL وجود دارد که در ادامه به معرفی آنها می پردازیم.
1. روش نخست – ایجاد URL کاربرپسند
در روش نخست، به اصطلاح یک بانک اطلاعاتی ایجاد شده است که لیستی از محصولات را نمایش می دهد و به کاربر اجازه می دهد تا بر روی یک محصول خاص کلیک کند تا به صفحه جزئیات آن محصول برود.
برای شروع باید کد زیر را ایجاد کرد:
public class Product
{
public string Description { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public float Price { get; set; }
}
در لیست محصولات ما به سادگی لیست محصولات را نمایش داده ایم:
زمانی که کاربران روی محصولات کلیک می کنند به صفحه جزئیات آن هدایت می شوند.
اکنون نگاهی به URL ایجاد شده کنید:
این تنها یک URL معمولی است که در بیشتر برنامه های ASP.NET MVC دریافت می کنید؛ به گونه ای که از طریق ID یک سری ردیف خاص که در پایگاه داده قرار دارند به سمت کنترلر عملگرا منتقل می شوند.
ما در اینجا به دنبال یک URL کاربرپسند هستیم. برای این کار یک روش جدید وجود دارد که شامل کد زیر می شود:
public class Product
{
public string Description { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public float Price { get; set; }
// Slug generation taken from http://stackoverflow.com/questions/2920744/url-slugify-algorithm-in-c
public string GenerateSlug()
{
string phrase = string.Format("{0}-{1}", Id, Name);
string str = RemoveAccent(phrase).ToLower();
// invalid chars
str = Regex.Replace(str, @"[^a-z0-9\s-]", "");
// convert multiple spaces into one space
str = Regex.Replace(str, @"\s+", " ").Trim();
// cut and trim
str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim();
str = Regex.Replace(str, @"\s", "-"); // hyphens
return str;
}
private string RemoveAccent(string text)
{
byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(text);
return System.Text.Encoding.ASCII.GetString(bytes);
}
}
در اینجا فهرست محصولات به روز شده است تا از Slug به عنوان یک پارامتر مسیر به جای ID استفاده شود:
<table >
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Image</th>
</tr>
</thead>
<tbody>
@foreach (var product in Model)
{
<tr>
<td><a href="/@Url.Action("Details", "Products", new { id = @product.GenerateSlug() })">@product.Name</a></td>
<td>@product.Price</td>
<td><img src="http://placehold.it/100x100"/></td>
</tr>
}
</tbody>
</table>
اکنون وقتی به صفحه جزئیات محصول می رویم، می توانم ببینیم که یک URL "کاربرپسند" ایجاد شده که حاوی نام محصول است:
اما در اینجا یک خطای جدید داریم. برنامه ASP.NET MVC انتظار یک پارامتر Route id را داشت، اما نتوانست آن را پیدا کند. دلیل این امر این است که عملکرد Details در کنترلر انتظار مقدار عددی صحیح را برای پارامتر id داشت. پس بیایید ادامه مسیر را با روش Routing تکمیل کنیم و از شر این ارور راحت شویم.
2. روش Routing
کد زیر را می نویسیم:
public ActionResult Details(int id)
{
...
}
اما اکنون به جای استفاده از یک عدد صحیح، بخش id نوشته شده دارای یک رشته کد است. چارچوب MVC در تلاش است تا رشته را به عدد صحیح تبدیل کند، اما نمی تواند این کار را انجام دهد و بنابراین یک مقدار null (نامعلوم) را عبور داده و سپس اخطار می دهد که پارامتر id نمی تواند یک مقدار null داشته باشد.
برای رفع این خطا باید RouteData را برای مسیر اصلاح کنیم تا مقدار پارامتر مسیر id شناسایی شود.
در این حالت خیلی ساده بررسی می کنیم که آیا پارامتر id وجود دارد یا خیر؟ اگر وجود داشت از یک عبارت منظم برای استخراج قسمت اول URL که حاوی شناسه عددی واقعی است استفاده می کنیم و آن مقدار عددی را به مقدار مسیر id اختصاص می دهیم:
public class SeoFriendlyRoute : Route
{
public SeoFriendlyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler)
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var routeData = base.GetRouteData(httpContext);
if (routeData != null)
{
if (routeData.Values.ContainsKey("id"))
routeData.Values["id"] = GetIdValue(routeData.Values["id"]);
}
return routeData;
}
private object GetIdValue(object id)
{
if (id != null)
{
string idValue = id.ToString();
var regex = new Regex(@"^(?<id>\d+).*$");
var match = regex.Match(idValue);
if (match.Success)
{
return match.Groups["id"].Value;
}
}
return id;
}
}
و آخرین قسمت، اضافه کردن یک راه (Route) جدید برای مسیر/محصولات/جزئیات/id است:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("ProductDetails", new SeoFriendlyRoute("products/details/{id}",
new RouteValueDictionary(new { controller = "Products", action = "Details" }),
new MvcRouteHandler()));
routes.MapRoute("Default", "{controller}/{action}/{id}", new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
}
تبریک! اکنون صفحه را رفرش کنید و از URL کاربرپسند خود لذت ببرید. اکنون پارامترها به درستی محدود شده اند، زیرا فقط قسمت عددی URL محصول که حاوی شناسه واقعی محصول است به عنوان پارامتر id منتقل می شود.
برای سئو، محتوا باید ایندکس بشود
اکنون وقت آن رسیده تا محتوای خود را هر چه سریع تر ایندکس کرده و به موتورهای جستجو اجازه دهید تا آن را به نمایش بگذارند.
برای این کار باید نقشه سایت در سرچ کنسول از قبل تعیین شده باشد. معمولا گوگل از نقشه هایی با فرمت XML پشتیبانی می کند. نقشه سایت شامل تمامی URL های سایت می شود. برای ساخت نقشه سایت یک API در چارچوب NET. وجود دارد که فیدهای ATOM و RSS را می سازد. برای یافتن API می توان از طریق System.ServiceModel.Syndication اقدام کرد.
در اینجا چیزی برای پشتیبانی کردن از سایت وجود ندارد و باید ابتدا از ساختار آن مطلع شویم:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.mikesdotnetting.com/</loc>
<lastmod>2015-12-01T12:00:00Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
در این فرمت باید به ریشه اصلی آن که urlest است و شامل گره های URL می شود، توجه کنیم. تنها گره loc است که مهم است، زیرا تعریف کننده URL سایت است. گرهای که مقدار lastmode را نشان می دهد، گویای آخرین تغییرات در محتوای URL است که با استاندارد W3C DateTime مطابقت دارد.
گره changefreq نیز اشاره به فرکانس تقریبی آخرین تغییرات URL دارد. در انتها نیز قادرید تا از priority برای بررسی صفحات وب خود استفاده کنید.
در ساخت نقشه سایت حتما به فاکتورهای سنجش میزان changefreq ، کلاسی برای نشان دادن نقشه سایت و آیتم های آن، گردآوری آیتم ها و روشی برای نظم بخشیدن به آنها و تبدیل آیتم ها به فرمت XML. در ادامه نیز یک کلاس برا نقشه سایت و آیتم های آن معرفی می کنیم:
public class SiteMap
{
public List<SiteMapItem> Items { get; set; }
}
public class SiteMapItem
{
public Uri Loc { get; set; }
public DateTime? LastMod { get; set; }
public ChangeFrequency ChangeFreq { get; set; }
public double? Priority { get; set; }
}
معرفی مقدار مجاز ChangeFrequency:
public enum ChangeFrequency
{
NotSet,
Always,
Hourly,
Daily,
Weekly,
Monthly,
Yearly,
Never
}
در ادامه نیز نوبت به کلاس SiteMapWriter است که مسئول پشت هم قرار دادن آیتم ها و تبدیل آنها به فرمت XML می باشد.
public class SiteMapWriter
{
private SiteMap _siteMap;
public SiteMapWriter(SiteMap siteMap)
{
_siteMap = siteMap;
}
public void WriteTo(XmlWriter writer)
{
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
var xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement(ns + "urlset",
_siteMap.Items
.Select(item => new XElement(ns + "url",
new XElement(ns + "loc", item.Loc),
item.LastMod.HasValue ? new XElement(ns + "lastmod", item.LastMod.Value.ToString("s") + "Z") : null,
item.ChangeFreq != ChangeFrequency.NotSet ? new XElement(ns + "changefreq", item.ChangeFreq.ToString().ToLower()) : null,
item.Priority.HasValue ? new XElement(ns + "priority", item.Priority.Value) : null
)
)
)
);
xml.Save(writer);
}
}
فایل robots.txt
این فایل موتورهای جستجو را هدف قرار می دهد تا به محتوای سایت دسترسی داشته باشند یا خیر. در واقع robots.txt را می توان راهنمای موتورهای جستجو برای مسیریابی سایت قلمداد کرد. این فایل دارای کد زیر است:
sitemap: http://www.mikesdotnetting.com/sitemap
user-agent: *
disallow: /downloads/
• خط اول اشاره به نقشه سایت دارد.
• خط دوم نیز اشاره به دستوراتی دارد که برای تمامی ربات ها طراحی شده است.
• خط سوم به ربات ها اجازه بررسی مسیر دانلودها را نمی دهد.
بسیاری از مالکین سایت علاقه ندارند تا خزنده های گوگل برخی از محتواهای آنها را بررسی کند. از این رو اقدام به محدود کردن آنها از طریق robots.txt می کنند؛ کاری که مطمئنا درست نیست و نباید انجام شود.
کدهای وضعیت HTTP
بسیاری از سایت های فعال مدام در حال اضافه و حذف کردن محتوا و صفحات سایت خود هستند. از این رو اغلب با کدهای وضعیت HTTP مواجه هستند. این کدها را باید زمانی ارائه دهیم که صفحه ای حذف شده و گوگل از آن بی خبر است. در واقع ما با این کار به خزنده های گوگل می فهمانیم که صفحه مورد نظر حذف شده و آن را از نتایج جستجوی خود حذف کنند.
301: انتقال دائمی URL
302: انتقال موقت URL
404: یافت نشدن صفحه
500: خطای داخلی سرور
پیکربندی صفحات خطای سفارشی با کد وضعیت HTTP صحیح
این بخش نحوه پیکربندی صفحات خطا را برای خطاهای 404 و 500 در Web Forms و MVC 5 و نسخه های پایین تر نشان می دهد. بیشتر نمونه های موجود shpw نحوه پیکربندی خطاهای سفارشی را با استفاده از customErrors در پرونده web.config پیکربندی می کنند. این روش تنها درصورتی باید مورد استفاده قرار گیرد که سایت ها در IIS 6 میزبانی شوند. توصیه ما این است که به جای آن از قسمت httpErrors در بخش system.webServer در فایل web.config استفاده کنید. در صورت استفاده از این روش باید قسمت customErrors را حذف کنید.