Exercício – Criar middleware personalizado

Concluído

Os desenvolvedores podem criar componentes de middleware personalizados para adicionar funcionalidade a um aplicativo ASP.NET Core. O middleware personalizado pode ser inserido em qualquer lugar no pipeline de middleware e pode ser usado com componentes de middleware internos, como visto neste exemplo:

Um diagrama mostrando o fluxo de uma solicitação por meio do pipeline.

A equipe de operações de rede da sua empresa está solucionando problemas de desempenho no ambiente de produção. O líder da sua equipe encarregou você de implementar alguns recursos para oferecer melhor suporte ao monitoramento em tempo real do aplicativo. O aplicativo deve registrar os detalhes da solicitação no console. Para cada solicitação, ele deve registrar o método de solicitação, o caminho e o código de status da resposta.

Neste exercício, você criará um componente de middleware personalizado que registra os detalhes da solicitação no console.

Adicionar middleware personalizado

Vamos modificar o aplicativo ASP.NET Core existente para incluir o middleware personalizado que registra os detalhes da solicitação no console.

  1. Abra o arquivo Program.cs se ele ainda não estiver aberto.

  2. Imediatamente antes de app.Run(), insira o seguinte código:

    app.Use(async (context, next) =>
    {
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
        await next(); 
    });
    

    No código anterior:

    • app.Use() adiciona um componente do middleware personalizado ao pipeline. O componente usa um objeto HttpContext e um objeto RequestDelegate como parâmetros.
    • O delegado grava o método de solicitação, o caminho e o código de status de resposta no console.
    • await next() chama o próximo componente de middleware no pipeline.

Teste as mudanças

  1. Pressione Ctrl+Shift+F5 para recompilar e reiniciar o aplicativo.

  2. Quando a janela do navegador for aberta, observe que o URL raiz exibe "Bem-vindo à Contoso!"

  3. Adicione /history ao URL e pressione Enter. O navegador será redirecionado para a página /about.

  4. No Visual Studio Code, pressione CTRL+Shift+P para abrir a paleta de comandos. Pesquise e selecione Console de Depuração: Concentre-se no Modo de Exibição do Console de Depuração para alternar para a guia Console de Depuração no painel inferior. Observe as seguintes linhas:

    GET / 200
    GET /about 200
    

    A saída do console mostra o método de solicitação, o caminho e o código de status de resposta para cada solicitação. A primeira linha mostra a solicitação do URL raiz e a segunda linha mostra a solicitação da página /about.

    Observação

    Seu navegador também pode solicitar /favicon.ico. Essa é uma solicitação padrão para o favicon de um site e pode ser ignorada.

  5. Deixe o aplicativo em execução para o próximo exercício.

Alterar a ordem do middleware

O aplicativo parece funcionar, mas há um problema. Você solicitou a página /history, mas a saída do console não a mostra. Esse comportamento ocorre porque o componente de middleware personalizado que registra os detalhes da solicitação foi adicionado após o middleware de reescrita de URL. O middleware de reescrita de URL. redireciona as solicitações de /history para /about e envia a resposta, e o componente de middleware personalizado não vê a solicitação. Vamos corrigir isso.

  1. Mova a linha app.Use() que você adicionou imediatamente antes da linha app.UseRewriter().

    O arquivo Program.cs completo deve ser assim:

    using Microsoft.AspNetCore.Rewrite;
    
    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    app.Use(async (context, next) =>
    {
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
        await next(); 
    });
    
    app.UseRewriter(new RewriteOptions().AddRedirect("history", "about"));
    
    app.MapGet("/", () => "Hello World!");
    app.MapGet("/about", () => "Contoso was founded in 2000.");
    
    app.Run();
    

    Agora, o componente de middleware personalizado é adicionado antes do middleware de reescrita de URL. O componente de middleware personalizado registra os detalhes da solicitação antes que o middleware de reescrita de URL processe a solicitação e a redirecione.

  2. Reinicie o aplicativo novamente e teste-o como antes. Dessa vez, a saída do Console de Depuração deve incluir a solicitação da página /history.

    GET / 200
    GET /history 200
    GET /about 200
    

    A saída do console agora mostra a solicitação da página /history logo antes de redirecionar para a página /about.

Corrigir o código de status

O aplicativo está quase pronto, mas há mais um problema. O código de status na saída do console é sempre 200, mesmo quando o aplicativo redireciona a solicitação. O código de status da solicitação /history deve ser um redirecionamento 302. O motivo desse comportamento é outro problema de ordem em que os componentes do middleware são processados.

O componente de middleware personalizado registra os detalhes no console e, em seguida, faz chama await next() para passar para o próximo componente de middleware. O problema é que a propriedade StatusCode do objeto Response é definida depois que o componente de middleware do terminal inicia a resposta. Vamos alterar o código para corrigir isso.

  1. No delegado que você adicionou, mova a linha Console.WriteLine() para depois da linha await next().

    O código atualizado deve ser assim:

    app.Use(async (context, next) =>
    {
        await next(); 
        Console.WriteLine($"{context.Request.Method} {context.Request.Path} {context.Response.StatusCode}");
    });
    

    Agora, o componente de middleware personalizado registrará os detalhes da solicitação depois que o componente de middleware do terminal definir o código de status de resposta.

  2. Reinicie e teste a solicitação /history novamente. A saída do Console de Depuração agora deve mostrar o código de status correto.

    GET / 200
    GET /history 302
    GET /about 200