Módulo 3 · Arquitetura MVC — Capítulo 07

Filters, Middlewares e Pipeline

O caminho que uma requisição percorre antes de chegar num Controller e depois de sair dele — middlewares e filters, as duas formas de interceptar esse fluxo.

1. O pipeline de middlewares

Toda requisição HTTP atravessa uma cadeia de componentes antes de chegar num Controller — o pipeline de middlewares. Cada middleware pode inspecionar/alterar a requisição, decidir passar adiante ou interromper, e fazer algo com a resposta no caminho de volta.

Exception HTTPS Auth Routing Controller resposta volta pelo mesmo caminho, na ordem inversa

Fig. 1 — Cada middleware decide se (e como) passa a requisição adiante — a resposta atravessa a mesma cadeia de volta.

C# Program.cs — ordem importa
var app = builder.Build();

app.UseExceptionHandler("/Erro");   // captura exceções de tudo que vem depois
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();
Atenção

A ordem de app.Use...() importa e é executada sequencialmente. UseAuthorization() antes de UseAuthentication(), por exemplo, tentaria checar permissões antes mesmo de saber quem é o usuário — um erro comum de configuração.

2. Escrevendo um middleware customizado

C# middleware simples de log de tempo
app.Use(async (context, proximo) =>
{
    var cronometro = Stopwatch.StartNew();

    await proximo(); // passa adiante no pipeline

    cronometro.Stop();
    Console.WriteLine($"{context.Request.Path} levou {cronometro.ElapsedMilliseconds}ms");
});

proximo() (o parâmetro next) é o que conecta este middleware ao próximo da cadeia — sem chamá-lo, o pipeline para ali, e nada depois dele (incluindo o Controller) chega a executar.

3. Filters — interceptando no nível do MVC, não do pipeline inteiro

Filters atuam num nível mais específico: em volta da execução de uma Action (ou Controller), não de toda requisição HTTP. Os quatro tipos mais comuns:

FilterQuando rodaUso típico
IAuthorizationFilterAntes de tudo — checagem de permissão[Authorize]
IActionFilterImediatamente antes/depois da ActionLog, validação cruzada, cache de resposta
IExceptionFilterQuando uma exceção não tratada escapa da ActionTratamento de erro centralizado
IResultFilterAntes/depois do resultado (View/JSON) ser geradoCompressão, cabeçalhos customizados
C# um ActionFilter customizado
public class LogarExecucaoFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext contexto)
        => Console.WriteLine($"Entrando em {contexto.ActionDescriptor.DisplayName}");

    public void OnActionExecuted(ActionExecutedContext contexto)
        => Console.WriteLine($"Saindo de {contexto.ActionDescriptor.DisplayName}");
}

// aplicado a uma Action específica
[ServiceFilter(typeof(LogarExecucaoFilter))]
public IActionResult Detalhes(int id) { ... }

4. Middleware vs. Filter — quando usar cada um

MiddlewareFilter
EscopoToda requisição HTTP, mesmo fora do MVCSó requisições que chegam a um Controller/Action MVC
Acesso ao ModelState/ActionContextNãoSim
Uso típicoAutenticação, HTTPS, arquivos estáticos, log genéricoAutorização por Action, validação, tratamento de exceção específico do MVC

5. Onde isso te leva

Com o pipeline inteiro mapeado — middlewares, DI, filters — o último capítulo deste módulo junta tudo num projeto prático completo, ligando de volta ao sistema de Pedidos construído no Módulo 2.

📌 Resumo do capítulo

  • O pipeline de middlewares processa toda requisição HTTP, em ordem, antes (e depois) de chegar num Controller.
  • A ordem de app.Use...() importa — autenticação sempre antes de autorização, por exemplo.
  • Filters atuam num nível mais específico do MVC: autorização, ação, exceção e resultado.
  • Use middleware para preocupações globais (toda requisição); use filter para preocupações específicas do MVC (Action/Controller).

✏️ Praticando

  1. Escreva um middleware customizado que adiciona um cabeçalho X-Tempo-Resposta com o tempo de processamento de cada requisição.
  2. Escreva um IActionFilter que loga, antes de cada Action, o Id do usuário autenticado (ou "anônimo" se não houver).
  3. Explique, em suas próprias palavras, um cenário em que um middleware seria mais apropriado que um filter, e vice-versa.