Фильтрация в 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 регистрирует следующих провайдеров:

Метод GetFilters возвращает в service locator все экземпляры IFilterProvider.

Порядок фильтров

Фильтры выполняются в следующем порядке:

  1. Авторизационные
  2. Методы
  3. Фильтры ответов
  4. Исключений

Внутри каждого типа фильтров значение Order определяет порядок выполнения, внутри каждого типа и порядка значение Scope определяет порядок для фильтров:

  1. First
  2. Global
  3. Controller
  4. Action
  5. Last

Например, фильтр 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. Благодарим за помощь в переводе Александра Белоцерковского.