Шрифт:
routes.IgnoreRoute("favicon.ico");
Этим определением мы указываем, что запрос вида http://some.domain/favicon.ico должен игнорироваться. Для более сложного варианта определим игнорирование маршрута к файлу favicon.ico для всех папок нашего сайта, а не только к корневой папке:
routes.IgnoreRoute("{*param}",
new { param = @"(.*/)?favicon.ico(/.*)?" });
Здесь мы уже используем два параметра, первый со значением {*param} определяет шаблон маршрута, в данном случае его можно описать как все пути, которые завершаются со значением параметра шаблона param. Второй параметр new{param=@" (.*/) ?favicon.ico (/.*)?"} задает определение параметра шаблона param в виде регулярного выражения, т. е. определяет, на что должна заканчиваться строка URL в клиентском запросе для того, чтобы маршрут игнорирования сработал.
Рассмотренные примеры работали в режиме, когда MVC Framework и механизм маршрутизации ASP.NET игнорируют запросы к существующим файлам. Однако имеет смысл перестать игнорировать такие запросы и самому обрабатывать запросы к группе определенных файлов, разрешая к ним доступ или запрещая его. Для того чтобы регулировать поведение маршрутизации ASP.NET в плане игнорирования запросов к существующим файлам, у класса RouteCollection, определяющего коллекцию маршрутов, есть булево свойство RouteExistingFiles. По умолчанию значение RouteExistingFiles установлено в false. Установив его в значение true, вы заставите механизм маршрутизации ASP.NET обрабатывать все запросы, в том числе и те, которые ведут на существующие файлы.
routes.RouteExistingFiles = true;
После этого любой запрос на локальный файл приведет к возникновению исключения и возврату клиенту информации об ошибке 404 "Страница не найдена". Теперь вы можете быть уверены в том, что пользователь не получит доступа ни к одному отдельному файлу на вашем сайте. Зато, определив правила игнорирования, для групп таких файлов вы сможете открыть доступ.
Рассмотрим пример использования игнорирования маршрутов для открытия доступа. Предположим, что в вашем проекте все стили, используемые на веб-страницах, расположены в папке some.domain/styles, а скрипты в some.domain/scripts. Теперь, чтобы открыть к ним доступ при включенном механизме маршуртизации для имеющихся файлов, достаточно определить следующие маршруты игнорирования:
routes.IgnoreRoute("styles/{*pathInfo}");
routes.IgnoreRoute("scripts/{*pathInfo}");
И в заключение рассмотрим последний простой пример, который часто используется на практике. Зачастую структура вашего проекта может содержать файлы с самыми разнообразными расширениями, которые вы отдаете пользователю по его запросу. Скажем, это может быть статический файл помощи с HTML-разметкой или текстовый файл с расширением txt, который может содержать информацию о лицензии. Механизм игнорирования маршрутов позволяет легко предоставить доступ к таким файлам даже при включенном механизме маршрутизации для имеющихся файлов. Например, следующий фрагмент кода разрешает загружать HTML- и TXT-файлы из корня сайта:
routes.IgnoreRoute("{file}.txt");
routes.IgnoreRoute("{file}.htm");
routes.IgnoreRoute("{file}.html");
Игнорирование маршрутов — это сильный инструмент, который по умолчанию позволяет создать правила для исключения из обработки запросов к виртуальным или несуществующим файлам. А после изменения RouteExistingFiles и включения механизма маршрутизации для всех запросов игнорирование маршрутов позволяет защитить все файлы от доступа и сформировать свои правила доступа к файлам на сайте.
Советы по использованию маршрутов
В этой главе мы рассмотрели механизм маршрутизации ASP.NET, используемые в нем классы, интерфейсы, свойства и коллекции. Мы показали, зачем нужен тот или иной параметр и для чего нужны коллекции параметров типа DataTokens или Constraints. В заключение главы мы расскажем о некоторых полезных советах по использованию механизма маршрутизации на практике.
Маршруты и валидация запросов
Как уже говорилось в этой главе, маршрутизация ASP.NET содержит механизм ограничений, который позволяет более гибко управлять обработкой маршрутов. Но кроме собственно поиска правильного маршрута, этот механизм позволяет также производить валидацию запросов еще на этапе поиска и обработки маршрута.
Представьте себе ситуацию, когда вы создаете маршрут, одним из параметров которого является число, определяющее год. Совершенно очевидно, что такое число имеет допустимые рамки, и его валидность может быть проверена еще на этапе сопоставления маршрутов. В листинге 6.1 приведен фрагмент кода, который определяет экземпляр класса, реализующий IRouteConstraint для такого рода проверки параметра.
Листинг 6.1. Класс, реализующий IRouteConstraint
public class YearConstraint : IRouteConstraint {
public bool Match(HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
if (parameterName == "year")
{
try
{
object yearValue = values["year"];
int year = Convert.ToInt32(yearValue);