Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Фильтры действий выполняются до и после работы метода контроллера. С их помощью мы можем изменить данные запроса, передаваемые в
объекте HttpRequestMessage
, так и внести изменения в результат метода - объект HttpResponseMessage
. Фильтры действий реализуют интерфейс IActionFilter:
public interface IActionFilter : IFilter { Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation); }
Параметр actionContext
содержит информацию о методе, а также несет ряд данных о запросе.
Параметр cancellationToken
представляет токен для отмены операции.
Параметр continuation
представляет выполняющийся метод. Вызов этого параметра собственно и предоставляет вызов метода, к которому
данный фильтр и будет применяться.
Создадим фильтр:
using System; using System.Diagnostics; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Web.Http.Controllers; using System.Web.Http.Filters; public class CustomActionAttribute: Attribute, IActionFilter { public async Task<HttpResponseMessage> ExecuteActionFilterAsync( HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation); { Stopwatch timer = Stopwatch.StartNew(); HttpResponseMessage result = await continuation(); double seconds = timer.ElapsedMilliseconds / 1000.0; result.Headers.Add("Elapsed-Time", seconds.ToString()); return result; } public bool AllowMultiple { get { return false; } } }
С помощью класса Stopwatch высчитываем время выполнения метода в секундах. Само выполнение метода представляет выражение await continuation()
.
Его итогом является объект HttpResponseMessage
, в который в виде заголовка мы добавляем время выполнения. Затем при обработке ответа на клиенте, либо
просто в браузере через инструменты разработчика мы можем получить это время.
Применение фильтра к методу:
public class ValuesController : ApiController { [CustomAction] public string Get(int id) { //........ } }
Хотя данный фильтр и позволяет обрабатывать ряд условий при вызове метода, но более удобным механизмом для создания фильтра действий является использование класса ActionFilterAttribute. Дело в том, что он определяет два метода:
OnActionExecutingAsync: выполняется до выполнения метода
OnActionExecutedAsync: выполняется после выполнения метода
Использование данных методов позволяет разграничить обработку до вызова метода и обработку после:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Web.Http.Controllers; using System.Web.Http.Filters; namespace WebApiApp.Filters { public class CustomActionAttribute : ActionFilterAttribute { private DateTime start; public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken) { return Task.Run(() => { start = DateTime.Now; }); } public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { return Task.Run(() => { DateTime end = DateTime.Now; actionExecutedContext.Response.Headers.Add("Start-Time", start.ToLongTimeString()); actionExecutedContext.Response.Headers.Add("End-Time", end.ToLongTimeString()); }); } } }
Каждый метод возвращает задачу, которая запускается методом Task.Run()
. Для отправки заголовков здесь используется контекст метода
actionExecutedContext
, который позволяет манипулировать ответом с помощью свойства actionExecutedContext.Response
.