Asp.net mvc framework
Шрифт:
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);
if (year >= 1900 && year <= 2100) return true;
}
catch
{
return false;
}
}
return false;
}
}
Для того чтобы использовать данный класс, необходимо определить маршрут с параметрами ограничения примерно так, как показано во фрагменте:
var constraints = new RouteValueDictionary
{
{"year", new YearConstraint}
};
routes.MapRoute("YearData",
"{controller}/{action}/{year}",
new { controller = "Data", action = "Index" },
new { year = new YearConstraint }
);
Вся прелесть этого механизма заключается в том, что вы можете использовать ограничение для параметров различных маршрутов. Таким образом, вы получаете централизованный механизм обработки и валидации входных параметров, который начинает работать еще до того, как в действие вступит контроллер.
Хранение маршрутов в базе данных
Порой определение маршрутов в файле global.asax — это недостаточно гибкий механизм для решения задачи, встающей перед разработчиком. Допустим, стоит задача передать права на создание, редактирование и удаление маршрутов некоему администратору. В таком случае предоставление доступа на редактирование файла global.asax может нарушить безопасность системы. В подобных ситуациях и когда необходимо выделить механизм доступа к созданию и редактированию маршрутов, обычно создается отдельное хранилище для данных маршрутов, которое используется для инициализации механизма маршрутизации при старте приложения.
Таким хранилищем может быть любой источник данных: от текстовых файлов и XML до отдельной базы данных, в таблицах которой хранятся определения маршрутов. Рассмотрим создание такой базы данных для хранения простейших маршрутов.
Для начала определим две таблицы, Routeitem и Param, для хранения данных о маршрутах так, как продемонстрировано на рис. 6.1 и 6.2.
Таблица Routeitem будет содержать информацию о маршрутах, а Param — соответственно, о параметрах для каждого маршрута.