Rose debug info
---------------

URL Rewriting в ASP.NET

URL Rewriting. Что это и зачем?

Основные цели для использования URL Rewriting две:

  1. Обеспечить лучшую индексацию в поисковых машинах. URL Rewriting позволяет включать основные слова прямо в URL, да и вообще, прямые ссылки приносят большие баллы в поисковых системах.
  2. Сделать пути к статьям независимыми от структуры сайта (чтобы в случае изменения структуры вашего сайта, ссылки из «избранного» оставались «живыми»).
  3. Сделать пути легкозапоминаемыми для людей.

Ну, вот пример. Мы пишем сайт какого-то журнала, и страницы в нем организованы по категориям (about, press, people, subscribe).
У нас есть страница “Show.aspx”, которая берет название категории из Querystring и делает выборку из базы. Запросы к странице Show.aspx сейчас выглядят так:

http://www.journal.ru/show.aspx?show=about
http://www.journal.ru/show.aspx?show=press
http://www.journal.ru/show.aspx?show=people
http://www.journal.ru/show.aspx?show=subscribe

Нас это не устраивает, и мы хотим изменить приложение так, чтобы адрес каждой страницы выглядел уникальным для поисковых машин.
Используем HttpModule для URL Rewriting.
Вот как будут выглядеть наши пути после перезаписи:
http://www.journal.ru/About.aspx
http://www.hournal.ru/Press.aspx
http://www.hournal.ru/People.aspx
http://www.hournal.ru/Subscribe.aspx

Всё это безобразие выглядит как 4 разных страницы на сайте (и очень радует поисковые сервера!), но на самом деле, это ссылки на Show.aspx. Используя метод HttpContext.RewritePath(), мы можем динамически переписывать входящие URL чтобы они обращались к Show.aspx, которая принимает аргументы из Querystring. Для этого, можно использовать событие в Global.asax:

void Application_BeginRequest(object sender, EventArgs e) {
        string fullOrigionalpath = Request.Url.ToString();
        if (fullOrigionalpath.Contains("/About.aspx")) {
            Context.RewritePath("/Show.aspx?show=about");
        }
        else if (fullOrigionalpath.Contains("/Press.aspx")) {
            Context.RewritePath("/Show.aspx?show=press");
        }
    }

Минусы этого способа: обычно бывает лень это писать, да легко можно запутаться и сделать ошибки. За вас уже все придумано и написано, можно просто воспользоваться одним из готовых компонентов:

UrlRewriter.net
UrlRewriting.net
Эти модули позволяют прописать вам в web.config правила перезаписи адресов. Например, используя UrlRewriter.Net, нужно записать в web.config привязку четырех URL к файлу Show.aspx:

<?xml version="1.0"?>

<configuration>
  <configSections>
    <section name="rewriter"  
             requirePermission="false" 
             type="Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter" />

  </configSections>
  <system.web>
    <httpModules>
      <add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>
    </httpModules>
  </system.web>

  <rewriter>
    <rewrite url="~/About.aspx" to="~/show.aspx?show=about" />
    <rewrite url="~/Press.aspx" to="~/show.aspx?show=press" />
    <rewrite url="~/People.aspx" to="~/show.aspx?show=people" />
    <rewrite url="~/Subscribe.aspx" to="~/show.aspx?show=subscribe" />
  </rewriter>    

</configuration>

HttpModule URL Rewriter-ы еще позволяют воспользоваться регулярными выражениями, чтобы не  заставлять разработчика добавлять в web.config вообще все динамические ссылки! ))) По-этому можно переписать правила немного иначе, так, чтобы любой адрес /[category-name].aspx работал через Show.aspx:

<rewriter>
    <rewrite url="~/(.+).aspx" to="~/show.aspx?show=$1" />
  </rewriter>

Это делает наш код очень гибким. Я думаю не нужно объяснять, для чего это нужно. Все очень легко и просто, а главное, никакого лишнего гемора.

Этот способ я использовал на www.kazved.ru, можете посмотреть, как это работает там.

В Apache+PHP для этого используется mod_rewrite.

3 комментария
3dmax 2008

Приветствую! Сейчас изучаю библиотеку UrlRewritingNet.. все отлично, вот только у меня возник такой вопрос, можно ли с помощью этогй библиотеки преобразовавать ссылки в коде на стадии построения страницы?
Не хочу сильно менять существующий код, куда лучше написать несколько регулярных выражений и преобразовывать уже готовые ссылки при помощи одного метода.

DrFaust 2008

Честноговоря в работу этого компонента не вникал, когда мне было нужно, просто поменял в коде генерацию ссылок с "page.aspx?id="+int на "/page/"+int+".aspx" :-)

3dmax 2008

:) уже разобрался :)).. у меня не получалось из-за того, что не совсем корректно унаследовал класс от RewritingRole. Все оказалось очень просто.(как и всегда.. порой так лень думать :))) )