Фильтры действий

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 29.10.2015

Фильтры действий выполняются до и после работы метода контроллера. С их помощью мы можем изменить данные запроса, передаваемые в объекте 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.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850