Поисковая оптимизация для ASP.NET разработчиков. MVC Extended Edition
Я уже писал статью на тему поисковой оптимизации для ASP.NET раработчиков. С тех пор прошло немного времени, появился MVC фреймворк, поэтому, думаю, стоит вернуться к рассмотрению этого вопроса.
В статье я затрону темы обработки шибок, переадресации, url rewriting и др.
WebForms, MVC и ViewState
Одним из главных преимуществ ASP.NET MVC фреймворка в сравнении с классическим ASP.NET WebForms является отсутствие ViewState – скрытого поля, в котором хранилась информации о состоянии веб-страницы.
<form name="_ctl0" method="post" action="page.aspx" id="_ctl0"> < input type="hidden" name="__VIEWSTATE" value="dDwtNTI0ODU5MDE1Ozs+ZBCF2ryjMpeVgUrY2eTj79HNl4Q=" /> .....some code </form>
С учетом того, что ViewState располагается в самом верху HTML кода веб-страницы (именно там, где должен быть основной контент), то это не сильно коррелировалось с правилами и рекомендациями SEO.
В MVC фреймворке такой пролемы нет – разметкой управляет сам разработчик. Одним из первых был сайт StackOverflow, который именно из-за этой проблемы перешел на новый фреймворк.
Заголовки и мета информация
С заголовками достаточно все просто. В WebForms всех версий это можно было сделать таким образом:
Page.Title = “Some Title”;
Или в разметке:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Title" %>
В ASP.NET MVC заголовки можно задать с помощью динамического свойства:
ViewBag.Title = “Some Title”; @ViewBag.Title // dynamic type
С мета информацией немного сложнее. В ASP.NET версий ниже 4.0 установка keywords и description выглядит таким образом:
HtmlMeta metaDesc = new HtmlMeta(); metaDesc.Name = "description"; metaDesc.Content = “Cool meta description"; Page.Header.Controls.Add(metaDesc); HtmlMeta metaKeywords = new HtmlMeta(); metaKeywords.Name = "keywords"; metaDesc.Content = “Cool, meta, keywords"; Page.Header.Controls.Add(metaKeywords);
В ASP.NET 4.0 появились специальные теги:
Page.MetaDescription = @"Cool meta description"; Page.MetaKeywords = @"Cool, meta, keywords";
В ASP.NET MVC это делается похожим с заголовками способом:
ViewBag.Description = “Cool meta description”; ViewBag.Keywords = “Cool, meta, keywords”;
Если нет желания (времени) объявлять метатеги для всех представлений, то можно определить текст по умолчанию, что делается таким способом:
@{ var description = ViewBag.Description ?? “Default description”; } <meta name="description" content=“@description" />
Urls и routing
Если наши страницы имеют такой вид:
http://site.com/Product.aspx?id={id}&action=0 http://site.com/Product.aspx?id={id}&action=1 http://site.com/Product.aspx?id={id}&action=2
то это досточно плохо. Горазко лучше иметь urls в таком виде:
http://site.com/product/{id}/edit http://site.com/product/{id}/info http://site.com/product/{id}/description
В ASP.NET WebForms можно переопределить имена путей с помощью метода context.RewritePath в методе Application_BeginRequest в Global.asax:
void Application_BeginRequest(object sender, EventArgs e) { HttpContext context = HttpContext.Current; string path = context.Request.Path.ToLower(); int lastContent = path.LastIndexOf("/product/"); if (lastContent == -1) return; int lastSlash = path.LastIndexOf('/'); string key = path.Substring(lastSlash + 1, path.Length - lastSlash - 1); context.RewritePath("~/default.aspx?id=" + key, false); }
В приведенном примере если вбить в браузер "/products/123", то вызовится страница "default.aspx?id=123", но пользователь этого не заметит.
В ASP.NET MVC и ASP.NET Dynamic Data для url rewriting и routing используется специальная библиотека System.Web.Routing.dll.
Вначале нам необходимо объявить набор правил роутинга и потом зарегистрировать их в приложении:
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 = "" }); // Parameter defaults routes.MapRoute( "ArticleRoute", "{article}/{controller}/{action}", new { article="Unknown", controller = "Home", action = "Index" } ); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes); }
Обработка ошибок в ASP.NET и перенаправления
Для обработки ошибок можно прописать в web.config такой код:
<customerrors defaultredirect="GenericError.aspx" mode="On"> <error statuscode="404" redirect="404.aspx"></error> <error statuscode="501" redirect="501.aspx"></error> </customerrors>
При возникновении ошибок с кодами 404 и 501 пользователь будет перенаправлен на соответствующие страницы.
Этот метод хорош всем, кроме того, что сервер возвратит 302, а потом 200 коды вместо 404.
Для того, чтобы перенаправить запрос на новую страницу при возникновении какой-либо ошибки, необходимо использовать метод Server.Transfer() или Response.Redirect().
protected void Application_Error(object sender, EventArgs e) { Exception ex = Server.GetLastError(); if (ex is HttpException) { if (((HttpException)(ex)).GetHttpCode() == 404) Server.Transfer("~/404.aspx"); } // Код для общих ошибок Server.Transfer("~/GenericError.aspx"); } }
И для страницы с ошибкой необходимо четко прописать:
protected void Page_Load(object sender, EventArgs e) { Response.StatusCode = 404; }
Для управления статус кодами можно использовать такой подход:
protected void Application_BeginRequest(object sender, EventArgs e) { var host = Request.Url.Host; if (host.Equals("someUrl", StringComparison.OrdinalIgnoreCase)) { var newUrl = new UriBuilder(Request.Url); newUrl.Host = "www." + host; Response.StatusCode = 301; Response.Status = "301 Moved Permanently"; Response.AddHeader("Location", newUrl.Uri.AbsoluteUri); Response.End(); return; } }
В данном случае мы говорим серверу, что страница перемещена навсегда (301 - moved permanently).
Также можно использовать методы Response.Redirect().(в чем отличие этих методов, можно почитать здесь)
- Response.Redirect(String) - Перенаправляет запрос по новому адресу и задает новый URL-адрес. Код 302.
- Response.Redirect(String, Boolean) - Перенаправляет клиента на новый адрес URL. Задает новый адрес URL и условия прекращения выполнения текущей страницы. Код 302.
В ASP.NET 4.0 проблемы с переадресацией были частично решены путем добавления новых методов:
- Response.RedirectPermanent(String) - Выполняет безвозвратное перенаправление с запрошенного URL-адреса на заданный URL-адрес. Код 301. http://stackoverflow.com/questions/224569/server-transfer-vs-response-redirectResponse.RedirectPermanent(String, Boolean) - Выполняет безвозвратное перенаправление с запрошенного URL-адреса на заданный URL-адрес и предоставляет возможность завершить ответ. Код 301.
В ASP.NET MVC и ASP.NET 4.0 также присутствуют дополнительные методы для работы с роутами:
- RedirectToRoute(Object) - Перенаправляет запрос на новый URL-адрес, используя значения параметров маршрута.
- RedirectToRoute(RouteValueDictionary) - Перенаправляет запрос на новый URL-адрес, используя значения параметров маршрута.
- RedirectToRoute(String) - Перенаправляет запрос на новый URL-адрес, используя имя маршрута.
- RedirectToRoute(String, Object) - Перенаправляет запрос на новый URL-адрес, используя значения параметров маршрута и имя маршрута.
- RedirectToRoute(String, RouteValueDictionary) - Перенаправляет запрос на новый URL-адрес, используя значения параметров маршрута и имя маршрута.
- RedirectToRoutePermanent(Object) - Выполняет постоянное перенаправление запроса с запрошенного URL-адреса на новый URL-адрес, используя значения параметров маршрута.
- RedirectToRoutePermanent(RouteValueDictionary) - Выполняет постоянное перенаправление запроса с запрошенного URL-адреса на новый URL-адрес, используя значения параметров маршрута.
- RedirectToRoutePermanent(String) - Выполняет постоянное перенаправление с запрошенного URL-адреса на новый URL-адрес, используя имя маршрута.
- RedirectToRoutePermanent(String, Object) - Выполняет постоянное перенаправление запроса с запрошенного URL-адреса на новый URL-адрес, используя значения параметров маршрута и имя маршрута, соответствующее новому URL-адресу.
- RedirectToRoutePermanent(String, RouteValueDictionary) - Выполняет постоянное перенаправление запроса с запрошенного URL-адреса на новый URL-адрес, используя значения параметров маршрута и имя маршрута.
В ASP.NET MVC то, что возвращает сервер, регулируется с помощью ActionResults:
public class HomeController : Controller { public ActionResult Index() { return View(); } }
ActionResults в ASP.NET MVC 3.0: - ContentResult - EmptyResult - FileContentResult - FilePathResult - FileStreamResult - JavaScriptResult - JsonResult - PartialViewResult - RedirectResult - RedirectToRouteResult - ViewResult - HttpNotFound - HttpStatusCodeResult
Жирным обозначены те ActionResults, которые относятся к вопросам SEO.
Примеры использования:
// Возвращаем ошибку 404 – не найдено public ActionResult SpecificResult() { return new HttpStatusCodeResult(404); } // или воспользуемся стандартным методом public ActionResult NotFound() { return HttpNotFound(); }
Подробнее об ActionResults можно почитать здесь.
Также необходимо упомянуть о Search Engine Optimization Toolkit & URL Rewriter, которые очень сильно упрощают работу веб-мастера.