среда, 2 декабря 2015 г.

Сила defaultValue в rewriteMap

Бывают ситуации, когда элемент <rewriteMap> в настройках IIS URL Rewrite на самом деле используется не как map (или dictionary), а просто как hash set. Т.е. когда достаточно проверить, что ключ есть в списке, а никакое value доставать не надо.

Пример. У каждого офиса корпорации раньше была своя личная страничка с адресом вроде /our-office-in-Donetsk/. А теперь надо их всех перенаправить на полный список всех офисов: /contact-us/. Это легко:

<rule name="Redirect all offices to the main Contact page">
  <match url="^our-office-in-([a-z]+)/$" />
  <action type="Redirect" url="contact-us/"/>
</rule>


Усложняем задачу: а что, если только некоторые страницы (допустим, с закрывшимися офисами) надо перенаправить, а остальные, вроде /our-office-in-Kyiv/ - оставить, как есть? Если список большой, то желательно использовать <rewriteMap>:

<rewriteMap name="ClosedOffices">
  <add key="Donetsk" value="closed" />
  <add key="Luhansk" value="closed" />
  <add key="Sevastopol" value="closed" />
</rewriteMap>

Тогда наше правило перенаправления может быть таким:

<rule name="Redirect closed offices to the main Contact page">
  <match url="^our-office-in-([a-z]+)/$" />
  <conditions>
    <add input="{ClosedOffices:{R:1}}" pattern="^closed$"/>
  </conditions>
  <action type="Redirect" url="contact-us/"/>
</rule>

Неплохо, но для каждой строчки в карте приходится повторять одно и то же value="closed". Это добавляет шум в код, и ошибиться легче (написал в одном месте close вместо closed, и работать уже не будет).

И тут есть небольшой трюк: атрибут value ведь использовать необязательно! Вместо этого можно делать наоборот - возвращать defaultValue, когда ни одного совпадения не найдено (если value не указано, то в случае совпадения возвращается пустая строка):

<rewriteMap name="ClosedOffices" defaultValue="open">
  <add key="Donetsk" />
  <add key="Luhansk" />
  <add key="Sevastopol"/>
</rewriteMap>

<rule name="Redirect closed offices to the main Contact page">
  <match url="^our-office-in-([a-z]+)/$" />
  <conditions>
    <add input="{ClosedOffices:{R:1}}" pattern="^open$" negate="true" />
  </conditions>
  <action type="Redirect" url="contact-us/"/>
</rule>

2 комментария:

KEHT комментирует...

А "[a-z]+" же не включает заглавные буквы как в городе?!

Valik комментирует...

Очень правильный вопрос. Майкрософт, как обычно, решила упростить жизнь разработчикам: по умолчанию IIS URL Rewrite нечуствителен к регистру, даже в регулярных выражениях.

Ratings by outbrain