Pular para o conteúdo
.NETMiddleware do ASP.NET Core
Módulo 03Construindo a Web API

Middleware do ASP.NET Core

iniciante 18 min de leitura·Atualizado · .NET 9
Resumo

Todo request no ASP.NET Core passa por um pipeline de componentes chamados middleware. Entender esse pipeline — e a ordem dele — é a base para tudo: autenticação, logging, tratamento de erros e roteamento.

1. Objetivos de Aprendizagem#

  • Explicar o pipeline de requisição e o conceito de next.
  • Escrever um middleware inline com Use.
  • Usar Run, Map e MapWhen para ramificar o pipeline.

2. Pré-requisitos#

  • Program.cs funcional (tópicos anteriores).

3. Conceito#

O diagrama abaixo resume o fluxo principal.

Carregando diagrama…

Um middleware é um componente que recebe o HttpContext e decide: processar e chamar o próximo (await next()), ou curto-circuitar (responder sem chamar o próximo). O pipeline é uma cadeia — a ordem de registro é a ordem de execução na entrada e a ordem inversa na saída.

O porquê de conhecer isso: 90% dos bugs de "meu UseAuthorization não funciona" são problemas de ordem no pipeline.

4. Mão na Massa#

4.1. Setup#

Nenhum pacote. Vamos escrever middleware inline no Program.cs.

4.2. Implementação Passo a Passo#

  1. Use — processa e continua o pipeline:
C#
app.Use(async (context, next) =>
{
    Console.WriteLine($"→ {context.Request.Method} {context.Request.Path}");
    await next(context);
    Console.WriteLine($"← {context.Response.StatusCode}");
});
  1. Run — terminal, não chama next:
C#
app.Run(async context =>
{
    await context.Response.WriteAsync("Pipeline terminal.");
});
  1. Map — ramifica por caminho:
C#
app.Map("/healthz", branch =>
{
    branch.Run(async context => await context.Response.WriteAsync("OK"));
});
  1. MapWhen — ramifica por predicado sobre o request:
C#
app.MapWhen(
    context => context.Request.Query.ContainsKey("debug"),
    branch => branch.Run(async context =>
        await context.Response.WriteAsync("Ramo de debug")));

4.3. Executando#

Shell
dotnet run

Acesse /healthz e /qualquer?debug=1 e observe cada ramo responder de forma diferente.

5. Exemplo Completo#

C#
var app = builder.Build();

app.Use(async (context, next) =>
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    await next(context);
    sw.Stop();
    context.Response.Headers["X-Elapsed-ms"] = sw.ElapsedMilliseconds.ToString();
});

app.Map("/healthz", b => b.Run(async c => await c.Response.WriteAsync("OK")));

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

6. Boas Práticas e Armadilhas#

FaçaEvite
Registrar middleware na ordem correta (erros → auth → routing)Colocar autenticação depois do roteamento dos controllers
Chamar await next(context) quando não for terminalEsquecer o next e curto-circuitar sem querer
Extrair middleware complexo para uma classe dedicadaAcumular lógica pesada inline no Program.cs
Atenção

não escreva no corpo da resposta e depois chame next esperando alterar o status — uma vez que a resposta começou (HasStarted), cabeçalhos e status não podem mais mudar.

7. Segurança e Produção#

  • O middleware de tratamento de erros deve ser o primeiro para capturar exceções de todos os componentes seguintes.
  • Middleware que loga o corpo do request deve ter cuidado com PII/LGPD (ver Módulo 16).

8. Exercícios#

  • Fácil: escreva um middleware que adicione o cabeçalho X-Request-Id.
  • Médio: transforme o middleware de cronômetro numa classe convencional (InvokeAsync) e registre com UseMiddleware<T>().
  • Desafio: use MapWhen para direcionar requests com Accept: text/plain a um ramo que responde em texto puro.

9. Resumo#

O pipeline é uma cadeia ordenada de middleware. Use continua, Run finaliza, Map/MapWhen ramificam. A ordem de registro define o comportamento.

10. Próximos Passos#

Módulo 16: um serviço de logging desacoplado por interface, injetado via DI.

11. Referências#

16-04 — Middleware do ASP.NET Core | Curso ASP.NET Core