Pull to refresh

Ограничение маршрутов в ASP.NET MVC

Reading time3 min
Views5.1K
Original author: David Hayden
Одна из реально удобных вещей в расширяемости ASP.NET MVC — это возможность накладывать ограничения и писать собственные ограничения для ваших маршрутов. Я склонен считать что добавление ограничей маршрутов(когда это возможно) — это отличная практика. Почему бы когда невалидные значения маршрута передаются в ваше приложение не позволить фреймворку ASP.NET MVC и модулю маршрутов самим заняться валидацией?


Ограничения маршрута

Использование ограничения маршрутов в ASP.NET MVC — это часть самого процесса маппинга маршрутов. Возьмём к качестве примера электронный магазин, который использует ID продукта в своих маршрутах чтобы показывать продукты в каталоге. Т.к. ID должен быть целочисленным в данном случае и может состоять только из 1-5 цифр, давайте укажем это как ограничение маршрута, так чтобы только верные ID-шники принимались в маршруте:

routes.MapRoute("Product", "Product/{id}",
 new { controller = "Products", action = "Details" },
 new { id = @"\d{1,5}" }); // Constraint


* This source code was highlighted with Source Code Highlighter.


Обратите внимание на то как легко указать что id это диапазон от 1 до 5 цифр с помощью регулярного выражения "\d{1,5}". Теперь, если кто-то введёт неверный маршрут, такой как:

/Product/abc

Он получит страницу с ошибкой(ксли не задана своя страница ошибок — стандартную «ресурс не найден»/«the resource cannot be found.»).

Custom Route Constraints

Ещё круче чем использование ограничений маршрутов в ASP.NET MVC является возможность создания собственных ограничений. Для создания собственного ограничения маршрута — всё что надо это создать класс, реализующий IRouteConstraint, для которого надо реализовать всего лишь один метод — Match.

Давайте создадим простое ограничение маршрута, проверющий имена сотрудников, которые передаются в части маршрута. Маршрут выглядит так:

routes.MapRoute("Employee", "Employee/{name}",
 new { controller = "Employees", action="Details" },
 new { name = new ExpectedValuesConstraint("john", "jane", "tom") });


* This source code was highlighted with Source Code Highlighter.


Заметьте добавление собственного класса ограничения маршрута под названием ExpectedValuesConstraint с перечнем имен, которые ожидаются в качестве поля {name} в маршруте.

Класс ExpectedValuesConstraint выглядит следующим образом:

public class ExpectedValuesConstraint : IRouteConstraint
{
 private readonly string[] _values;

 public ExpectedValuesConstraint(params string[] values)
 {
    _values = values;
 }

 public bool Match(HttpContextBase httpContext, Route route,
    string parameterName, RouteValueDictionary values,
    RouteDirection routeDirection)
 {
    return _values.Contains(values[parameterName].ToString(),
     StringComparer.InvariantCultureIgnoreCase);
 }
}


* This source code was highlighted with Source Code Highlighter.


В этом случае parameterName будет «name», а затем мы просто берем значение имени из RouteValueDictionary и проверяем входит ли имя в список значений, переданных конструктору, когда был произведен маппинг маршрута. Если имя переданное в маршрут не равно «john», «jane», или «tom» — в этом случае пользователь будет отправлен на дефолтную страницу ошибки «ресурс не найден»(the resource cannot be found").

Вывод

Всякий раз как вы можете добавить ограничение маршрута к вашим маршрутам — добавляйте. Позвольте движку маршрутов помочь проверять входные данные для вашего приложения и возвращать ошибки в случае их несоответствия ожиданиям. Обратите внимание, что можно создавать достаточно всеобхватывающие маршруты когда вы хотите обрабатывать значения фиктивных маршрутов в приложении. На этот раз всё.

Tags:
Hubs:
Total votes 28: ↑17 and ↓11+6
Comments3

Articles