Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Фильтры действий позволяют нам проконтролировать входной контекст запроса при доступе к действию, а также выполнить определенные действия по завершению работы метода действий. Например, мы можем изменить выходной результат метода.
Фильтр действий должен реализовать интерфейс IActionFilter:
public interface IActionFilter { void OnActionExecuting(ActionExecutingContext filterContext); void OnActionExecuted(ActionExecutedContext filterContext); }
Либо мы должны унаследовать новый фильтр от абстрактного класса ActionFilterAttribute
, который уже реализует интерфейс
IResultFilter:
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
Метод OnActionExecuting
вызывается перед вызовом метода действий. А метод OnActionExecuted
- после.
С помощью метода OnActionExecuting
можно получить информацию о запросе, изменить ее либо вовсе отменить запрос. Передаваемый
в метод объект ActionExecutingContext
является производным от класса ControllerContext
и определяет следующие два дополнительных свойства:
Свойство | Тип | Описание |
ActionDescriptor | ActionDescriptor | Предоставляет информацию о вызываемом методе действия |
Result | ActionResult | Результат метода действий |
С помощью свойства Result
мы можем отменить результат действия, присвоив этому свойству другой результат действия.
В метод OnActionExecuted
в качестве параметра передается объект ActionExecutedContext
, который также является
производным от класса ControllerContext
. Он определяет некоторые дополнительные свойства:
Свойство | Тип | Описание |
ActionDescriptor | ActionDescriptor | Предоставляет информацию о вызываемом методе действий |
Canceled | bool | Хранит значение, показывающее, отменен ли вызов действия. Если имеет значение true, если вызов действия был отменен другим фильтром |
Exception | Exception | Возвращает исключение, выбрасываемое данным методом действий или другим фильтром |
ExceptionHandled | bool | Хранит значение, показывающее, обработано ли исключение. Если имеет true, если исключение обработано |
Result | ActionResult | Результат метода действий |
В качестве примера мы можем создать следующий фильтр действия:
public class MyActionAttribute : FilterAttribute, IActionFilter { public void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.Write("Действие выполнено"); } public void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Request.Browser.Browser=="Opera") { filterContext.Result = new HttpNotFoundResult(); } } }
И использование:
[MyAction] public ActionResult Index() { return View(); }
Здесь в методе OnActionExecuting
в случае, если клиент использует браузер Opera (например, мы хотим запретить поддержку своего
сайта для этого браузера), то мы возвращаем клиенту статусный код 404.
А в методе OnActionExecuted
мы добавляем в выходной поток строку.
Фильтры результатов во многом похожи на фильтры действий, поскольку так же могут срабатывать как до возвращения результата действия, так и после. Фильтры результатов реализуют интерфейс IResultFilter:
public interface IResultFilter { void OnResultExecuting(ResultExecutingContext filterContext); void OnResultExecuted(ResultExecutedContext filterContext); }
Метод OnResultExecuting
вызывается перед тем, как метод действия начнет возвращать результат действия.
А метод OnResultExecuted
- после того, как метод действия возвратил результат. Эти методы в качестве параметров принимают объекты
ResultExecutingContext
и ResultExecutedContext
, которые аналогичны объектам OnActionExecuting
и
OnActionExecuted
соответственно.
Например, мы можем выводить в выходной поток имя пользователя (если он авторизован) и текущее время запроса к серверу:
using System; using System.Web; using System.Web.Mvc; namespace Filters.Filters { public class MyResultAttribute: FilterAttribute, IResultFilter { public void OnResultExecuted(ResultExecutedContext filterContext) { filterContext.HttpContext.Response.Write("Время текущего запроса HTTP: " + filterContext.HttpContext.Timestamp); } public void OnResultExecuting(ResultExecutingContext filterContext) { filterContext.HttpContext.Response.Write("Текущий пользователь: " + filterContext.HttpContext.User.Identity.Name); } } }
Как говорилось в начале главы, фильтры действий и фильтры результатов объединены в одну реализацию - абстрактный класс ActionFilterAttribute, который объединяет черты обоих фильтров:
public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter { public virtual void OnActionExecuting(ActionExecutingContext filterContext){} public virtual void OnActionExecuted(ActionExecutedContext filterContext){} public virtual void OnResultExecuting(ResultExecutingContext filterContext) {} public virtual void OnResultExecuted(ResultExecutedContext filterContext) {} }
Мы можем реализовать только те методы, которые нам нужны, либо сразу все, что делает данный класс довольно гибким.