Открытая коллекция знаний

OpenU.Ru

Поисковая оптимизация сайтов, работающих на .NET

Перевод url в нижний регистр на ASP.NET MVC

В том числе по правилам именования классов и методов C# по умолчанию формируются имена контроллеров и методов действий с большой буквы. Соответственно, получаемые url имеют вид /Controller/Action. Всё бы ничего, но для поисковых систем адреса /Controller/Action и /controller/action — два разных адреса, не смотря на то, что они отдают одинаковое содержимое. Вообще для Microsoft характерно довольно халатное отношение к url-стабильности адресов, в особенности всё плохо с грамотной организацией url для поисковых систем.

Итак, нужно, чтобы все формируемые адреса проектом MVC на платформе .NET получались в нижнем регистре, а в случае ввода в адресную строку символов не нижнего регистра, производился редирект в нижний регистр. Для этого в классе RouteConfig (файл RouteConfig.cs) в методе RegisterRoutes нужно задать значение routes.LowercaseUrls = true:

public static void RegisterRoutes(RouteCollection routes)
{
 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//...
 routes.LowercaseUrls = true;
//...
}

Затем в файл Global.asax надо добавить метод Application_BeginRequest:

protected void Application_BeginRequest(object sender, EventArgs e)
{
  //Не редиректим на нижний регистр метод "post" или images/css/js
  bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
  if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)
  {
    string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
   if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
   {
     //не меняем регистр параметров
     lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query;

     Response.Clear();
     Response.Status = "301 Moved Permanently";
     Response.AddHeader("Location", lowercaseURL);
     Response.End();
   }
  }
}

Всё. Теперь во-первых, при вызове, например, метода @Html.ActionLink(«Контакты», «Contact», «Home») сформируется url вида /home/about вместо /Home/About. А во-вторых, при заходе по второму адресу клиенту будет отдана 301 ошибка переадресации на /home/about.

Второй метод — использование URL Rewriting. Для этого в файле Web.config в секции system.webServer нужно создать секцию <rewrite> и в неё поместить правило — создать ещё одну секцию <rules> со следующим правилом, назовём его «Lower case url redirect»:

<system.webServer>
 <rewrite>
  <rules>
   <rule name="Lower case url redirect" stopProcessing="true">
    <match url=".*[A-Z].*" ignoreCase="false" />
    <action type="Redirect" url="{ToLower:{R:0}}" redirectType="Permanent" /> 
   </rule> 
  </rules>
 </rewrite>
</system.webServer>

И всё также, как в первом случае, надо устанавливать routes.LowercaseUrls = true в методе RegisterRoutes, чтобы те же выражения Razor при формировании маршрута url для обращений к контроллерам выдавали идеологически выдержанные url в нижнем регистре. Помимо настройки правил формирования и переадресации url в нижнем регистре, нужно избавиться от дублей url для контроллера Home/Index и переадресации с Index на корневую папку других контроллеров, а также добиться однозначности url-адресов со слешем или без в конце адреса.