Quem trabalha com back-end de aplicações web, sabe a necessidade de ter o controle do fluxo da sua aplicação. Filtros, autorização, tokens e desserialização são algumas das necessidades mais comuns no mundo back-end.
Quando trabalhamos com .NET Core, esse controle é extremamente simplificado, pois ele foi arquitetado para ter ganchos e cada parte de uma requisição. Isso significa que podemos injetar código em diversas partes da pipeline da requisição, sem a necessidade workarounds (gambs, para os íntimos).

Isso abre diversas oportunidades para escrevermos código de boa qualidade, e com uma única responsabilidade. Para exemplificar o uso dos ganchos oferecidos, criei uma aplicação WebApi simples, com os seguintes filtros implementados: Resource Filter, Action Filter, Exception Filter e Result Filter; alguns exemplos para abrir o caminho, e o restante fica por sua necessidade em suas aplicações.
Filtros de Recurso
Tem a função de checar algum recurso de requisição, como cache ou valores de formulários antes do binding. Implementa a interface IResourceFilter:
public class ResourceFilter : IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
Console.WriteLine("Passando pelo Resource Filter ANTES do metodo");
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
Console.WriteLine("Passando pelo Resource Filter DEPOIS do metodo");
}
}
Ainda no Resource Filter, temos acesso ao ModelState, Session, ao objeto RouteData (onde podemos, inclusive, alterar o valor de um parâmetro de rota) e muitas outras propriedades.
Action Filter
Esse filtro é chamado logo antes e logo depois da ACTION, por isso, já temos acesso a uma instância do controller, e do ModelState também. Implementa a interface IActionFilter:
public class ActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
Console.WriteLine("Passando pelo Action Filter ANTES do metodo");
}
public void OnActionExecuted(ActionExecutedContext context)
{
Console.WriteLine("Passando pelo Action Filter DEPOIS do metodo");
}
}
Exception Filter
Uma classe especial de filtros, chamada somente em caso da action lançar uma exceção não tratada, muito utilizada para logging e tratamento da mensagem para uma forma amigável. Implementa a interface IExceptionFilter:
public class ExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
Console.WriteLine("Uma exceção não tratada ocorreu na action");
}
}
Nesse filtro, temos acesso ao ModelState também, e também temos como acessar a exceção que foi lançada.
Result Filter
Já nesse último filtro, é o passo antes de retornar a resposta para o usuário. Aqui, já temos o retorno da Action, e podemos adicionar headers, logging de sucesso e do resultado gerado, entre outras informações. Implementa a interface IResultFilter, com dois métodos: OnResultExecuting e OnResultExecuted. No primeiro é onde podemos alterar a resposta, é a nossa última chance de alterar algo antes de retornar para o usuário. No segundo método, a resposta já foi retornada, e não há mais como alterar nada.
public class ResultFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
Console.WriteLine("Passando pelo result filter antes de retornar ao usuario.");
}
public void OnResultExecuted(ResultExecutedContext context)
{
Console.WriteLine("Passando pelo result filter apos retornar ao usuario, ja nao podemos alterar a resposta.");
}
}
Para adicionar esses filtros que criamos no pipeline das requisições (de forma global, para exemplificar), adicionamos esses filtros ao declarar o uso do MVC na classe Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => {
options.Filters.Add(new ResourceFilter());
options.Filters.Add(new ActionFilter());
options.Filters.Add(new ExceptionFilter());
options.Filters.Add(new ResultFilter());
});
}
Rodando nossa aplicação, chamando o controller Teste (está no código fonte citado no início do artigo), temos o seguinte resultado no console:

É importante lembrar que podemos criar mais de um filtro do mesmo tipo e adicionar ao pipeline, é uma ferramenta de extrema importância para o desacoplamento de código e que poucos usam com seu total potencial. Neste exemplo simples, usamos somente o console para exemplificar, mas as possibilidades são inúmeras.
Não pare com os estudos, e busque implementar essa funcionalidade em seus projetos no trabalho ou estudo para fixar o conhecimento.
Um forte abraço, e até a próxima!



