Фильтрация в ASP.NET MVC 3
Иногда есть необходимость в совершении действий перед или после выполнения метода. Для этого в ASP.NET MVC есть фильтры, классы, предоставляющие возможности декларативного или программного объявления действий, которые будут выполнены перед или после выполнения методов контроллера.
Проект для Visual Studio можно скачать здесь: Download.
Типы фильтрации
В ASP.NET MVC реализована поддержка следующих типов фильтров:
- Авторизации. Данные фильтры реализуютIAuthorizationFilter и позволяют выносить решения об авторизации и выплонении методы. Примерами авторизационных фильтров являются классы AuthorizeAttribute и RequireHttpsAttribute. Данные фильтры выполняются перед всеми другими фильтрами.
- Фильтры методов, реализующие IActionFilter и оборачивающие выполнение методов. Интерфейс IActionFilter предоставляет два метода OnActionExecuting и OnActionExecuted, выполняющиеся перед методом и после соответственно.
- Результатов, реализующие IResultFilter и оборачивающие выполнение объекта ActionResult. IResultFilter объявляет два метода: OnResultExecuting и OnResultExecuted, выполняющиеся перед методом и после соответственно. Пример фильтра: класс OutputCacheAttribute.
- Исключений, реализующие IExceptionFilter и выполняющиеся, если во время выплонения выбрасывается необрабатываемое исключение. Эти фильтры могут использоваться для логгирования и отображения страницы ошибки, примером фильтра является класс HandleErrorAttribute.
Класс Controller реализует каждый из интерфейсов этих фильтров, вы можете реализовать любой из фильтров для любого контроллера с помощью переопределения метода контроллера On<Filter>. Например, переопределить метод OnAuthorization или любой из нижеследующих:
Фильтры в ASP.NET MVC
ASP.NET MVC включает следующие фильтры, реализованные в виде атрибутов. Данные фильтры могут быть применены на уровне метода, контроллера и приложения.
- AuthorizeAttribute. Аутентификация, (опционально) авторизация.
- HandleErrorAttribute. Обработка исключений.
Фильтр не перехватывает исключения до тех пор, пока в Web.config не включен элемент customErrors. - OutputCacheAttribute. Кэширование вывода.
- RequireHttpsAttribute. Принуждает небезопасный HTTP-трафик идти по каналу HTTPS.
Создание фильтра
Фильтр можно создать:
- Переопределив метод контроллера On<Filter>
- Создать класс-атрибут, наследующийся от ActionFilterAttribute и применяющий атрибут на контроллер или метод контроллера.
- Зарегистрировав фильтр с помощью провайдера фильтра (FilterProviders).
- Зарегистрировав глобальный фильтр с помощью класса GlobalFilterCollection.
Фильтр может реализовывать абстрактный класс ActionFilterAttribute. Некоторые фильтры, например AuthorizeAttribute, реализуют FilterAttribute напрямую. Авторизационные фильтры всегда вызываются перед вызовом метода и другими фильтрами. Другие фильтры, например OutputCacheAttribute, реализуют абстрактный класс ActionFilterAttribute, который позволяет фильтру выполнится перед или после выполнения метода.
В примере показана стандартная реализация класса HomeController с использованием атрибута HandleError на уровне всех методов контроллера.
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
}
Провайдеры фильтров
Провайдеры фильтров регистрируются с помощью статического свойства Providers. Метод GetFilters(ControllerContext, ActionDescriptor) собирает фильтры со всех провайдеров в один список. Провайдеры могут быть зарегистрированы в любом порядке.
По умолчанию ASP.NET MVC регистрирует следующих провайдеров:
- Filters для глобальных фильтров.
- FilterAttributeFilterProvider для атрибутов фильтров.
- ControllerInstanceFilterProvider для экземпляров контроллеров.
Метод GetFilters возвращает в service locator все экземпляры IFilterProvider.
Порядок фильтров
Фильтры выполняются в следующем порядке:
- Авторизационные
- Методы
- Фильтры ответов
- Исключений
Внутри каждого типа фильтров значение Order определяет порядок выполнения, внутри каждого типа и порядка значение Scope определяет порядок для фильтров:
Например, фильтр OnActionExecuting(ActionExecutingContext), имеющий значение свойства Order 0 и scope First, выполняется перед фильтром с Order 0 и scope Action. Фильтры исключений выполняются в обратном порядке, и фильтры исключения, имеющие Order 0 и scope First будут выполнены после фильтров методов с Order 0 и scope Action.
Порядок выполнения фильтров, имеющих один тип, порядок и scope, не определен.
Фильтры OnActionExecuting(ActionExecutingContext), OnResultExecuting(ResultExecutingContext), OnAuthorization(AuthorizationContext) выполняются последовательно, фильтры OnActionExecuted(ActionExecutedContext), OnResultExecuting(ResultExecutingContext), OnException(ExceptionContext) выполняются в обратном порядке.
Отмена выполнения фильтров
Вы можете отменить выполнение фильтра в методах OnActionExecuting и OnResultExecuting, с помощью установки свойства Result в не-NULL значение. Любые ожидающие выполнения фильтры OnActionExecuted и OnActionExecuting не будут вызваны. Метод OnActionExecuted будет вызван для предыдущих вызванных фильтров. Оба метода OnResultExecuting и OnResultExecuted будут вызваны.
Благодарности
Это перевод оригинальной статьи Filtering in ASP.NET MVC. Благодарим за помощь в переводе Александра Белоцерковского.
Comments
- Anonymous
April 11, 2012
А не правильнее было бы назвать статью "Фильтры в ASP.NET MVC", а то при чтении названия в голову приходит мысль о фильтрации данных, а не об атрибутах?