Самый очевидный способ — использование перенаправлений (redirect) всех некорректных адресов на один корректный. Этот способ не только устранит дублирование контента, но и поможет перенести «ссылочную ценность» на одну страницу. Для перенаправления используется статусы HTTP 30x. В нашем случае идеально подойдет статус "301 Moved Permanently", сообщающий клиенту (поисковику, браузеру и т.п.), что запрашиваемый ресурс следует загрузить с другого адреса.
Вообще, перенаправления (redirect) можно настроить на уровне IIS, используя решение типа ISAPI_Rewrite. Также инструменты подмены URL (UrlRewriter.NET, UrlRewriting.NET) могут выполнять перенаправления. Но в нашем случае такие способы не годятся, потому что модуль, осуществляющий redirect должен иметь связь с базой данных или другим хранилищем сущностей. Иначе адрес вида http://somesite.ru/category/13/
не удастся преобразовать к http://somesite.ru/category/13/текстовое-описание-категории
. Итак, единственное решение — вручную написать код, осуществляющий redirect в случае отличия текущего URL от корректного. Такой код обычно жестко связан с конкретной предметной областью, поэтому сложно привести общий пример. Для ASP.NET код может выглядеть так:
public static class UrlHelper
{
public static void CheckUrlcanonical()
{
HttpContext context = HttpContext.Current;
string currentLocation = context.Request.Path.ToLower();
string canonicalLocation = GetCanonicalLocation() 1;
if (currentLocation != canonicalLocation) 2
{
context.Response.Status = "301 Moved Permanently"; 3
context.Response.AddHeader("Location", canonicalLocation)
}
}
}
1 — метод GetCanonicalLocation
возвращает канонический адрес для запрашиваемой страницы, возможно, обращаясь к слою доступа к данным или сервисам.
2 — проверяем, является ли текущей адрес каноническим
3 — осуществляем redirect — устанавливаем статус 301 и путь для перенаправления.
Метод UrlHelper.GetCanonicalLocation()
можно вызывать в обработчике Page_Load()
соответствующей страницы или глобально для всего приложения — в Global.asax (Application_BeginRequest()
)