Поисковая оптимизация для ASP.NET разработчиков. MVC Extended Edition

пятница, 10 июня 2011, Александр Краковецкий

Я уже писал статью на тему поисковой оптимизации для 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, которые очень сильно упрощают работу веб-мастера.


Ищите нас в интернетах!

Комментарии

Свежие вакансии