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 integrados, como visto neste exemplo:

Um diagrama mostrando o fluxo de uma solicitação através 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 equipa encarregou-o de implementar algumas funcionalidades para melhor suportar a monitorização em tempo real da aplicação. O aplicativo deve registrar os detalhes da solicitação no console. Para cada solicitação, ele deve registrar o método da solicitação, o caminho e o código de status da resposta.

Neste exercício, você cria 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 middleware personalizado que registra detalhes da solicitação no console.

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

  2. Imediatamente antes 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 de middleware personalizado ao pipeline. O componente usa um HttpContext objeto e um RequestDelegate objeto como parâmetros.
    • O delegado grava o método de solicitação, o caminho e o código de status da resposta no console.
    • await next() chama o próximo componente de middleware no pipeline.

Testar as alterações

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

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

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

  4. No Visual Studio Code, pressione Ctrl+Shift+P para abrir a paleta de comandos. Procure por e selecione Debug Console: Focus on Debug Console View para mudar para o separador Debug Console 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 para a URL raiz e a segunda linha mostra a solicitação para a /about página.

    Nota

    Seu navegador também pode solicitar /favicon.ico. Esta é 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 /history página, mas a saída do console não a mostra. Esse comportamento ocorre porque o componente de middleware personalizado que registra detalhes da solicitação foi adicionado após o middleware de regravação de URL. O middleware do reescritor 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 app.Use() linha adicionada imediatamente antes da app.UseRewriter() linha.

    O arquivo de Program.cs completo deve ter esta aparência:

    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 regravação de URL. O componente de middleware personalizado registra os detalhes da solicitação antes que o middleware do reescritor de URL processe a solicitação e a redirecione.

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

    GET / 200
    GET /history 200
    GET /about 200
    

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

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 /history solicitação deve ser um redirecionamento 302. A razão para esse comportamento é outro problema de ordem em que os componentes de middleware são processados.

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

  1. No delegado adicionado, mova a Console.WriteLine() linha para depois da await next() linha.

    O código atualizado deve ter esta aparência:

    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 de terminal definir o código de status de resposta.

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

    GET / 200
    GET /history 302
    GET /about 200