Implementação, escopo e ordem
ResumoAction Filters executam código antes e depois das ações, ideais para lógica transversal (logging, validação, medição). Vemos como implementá-los, seus escopos (global, controller, ação) e a ordem de invocação.
1. Objetivos de Aprendizagem#
- Implementar um
IActionFilter(sync e async). - Registrar filtros em três escopos.
- Entender a ordem de execução dos filtros.
2. Pré-requisitos#
- Validação e ModelState (Módulo 27).
3. Conceito#
Filtros rodam dentro do pipeline do MVC, envolvendo a execução da ação. Um Action Filter tem OnActionExecuting (antes) e OnActionExecuted (depois). O porquê: extrair código repetido dos controllers (ex.: checar ModelState, logar entrada/saída) para um único lugar reutilizável.
Escopos: global (todas as ações), controller (via atributo na classe) e ação (via atributo no método). A ordem padrão é global → controller → ação na entrada, e inversa na saída; Order permite ajustar.
4. Mão na Massa#
4.1. Setup#
Sem pacotes novos.
4.2. Implementação Passo a Passo#
- Filtro de logging:
using Microsoft.AspNetCore.Mvc.Filters;
public class LogActionFilter : IActionFilter
{
private readonly ILoggerManager _logger;
public LogActionFilter(ILoggerManager logger) => _logger = logger;
public void OnActionExecuting(ActionExecutingContext context) =>
_logger.LogInfo($"Executando {context.ActionDescriptor.DisplayName}");
public void OnActionExecuted(ActionExecutedContext context) =>
_logger.LogInfo($"Executado {context.ActionDescriptor.DisplayName}");
}
- Registro como serviço + escopo global:
builder.Services.AddScoped<LogActionFilter>();
builder.Services.AddControllers(o => o.Filters.Add<LogActionFilter>()); // global
- Escopo controller/ação com atributo de tipo:
[ServiceFilter(typeof(LogActionFilter))]
public class ProdutosController : ControllerBase { }
4.3. Executando#
Chame qualquer endpoint e observe as mensagens de entrada/saída no log.
5. Exemplo Completo#
Ordem com Order:
[ServiceFilter(typeof(LogActionFilter), Order = 2)]
[HttpGet]
public IActionResult Get() => Ok();
Menor Order executa primeiro na entrada.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Usar ServiceFilter/TypeFilter para filtros com dependências | Instanciar filtros com new perdendo a DI |
| Filtros pequenos e focados | Colocar regra de negócio pesada no filtro |
| Escolher o escopo mínimo necessário | Aplicar globalmente algo que só serve a um controller |
Atenção
[TypeFilter]e[ServiceFilter]resolvem dependências via DI; um atributo simples ([MyFilter]) que herda deAttributenão consegue injetar serviços diretamente.
7. Segurança e Produção#
- Filtros de log não devem registrar corpo com PII (LGPD) — logue metadados, não payloads sensíveis.
8. Exercícios#
- Fácil: crie um filtro que meça o tempo da ação e adicione um header.
- Médio: aplique um filtro só a um controller.
- Desafio: demonstre a diferença de ordem entre escopo global e de ação.
9. Resumo#
Action Filters encapsulam lógica transversal com hooks antes/depois da ação, em três escopos e com ordem configurável. ServiceFilter/TypeFilter habilitam injeção de dependência.
10. Próximos Passos#
A seguir, extraímos a validação de ModelState para um Action Filter reutilizável.
11. Referências#
- Microsoft Learn — Filtros no ASP.NET Core
- Microsoft Learn — ServiceFilter e TypeFilter
- Microsoft Learn — Ordem de execução dos filtros