Übung: Erstellen benutzerdefinierter Middleware

Abgeschlossen

Entwickler können benutzerdefinierte Middleware-Komponenten erstellen, um einer ASP.NET Core-App Funktionen hinzuzufügen. Benutzerdefinierte Middleware kann an einer beliebigen Stelle in der Middlewarepipeline eingefügt und mit integrierten Middleware-Komponenten verwendet werden, wie in diesem Beispiel gezeigt:

Diagramm: Flow einer Anforderung in der Pipeline

Das Netzwerkbetriebsteam Ihres Unternehmens behandelt Leistungsprobleme in der Produktionsumgebung. Ihre Teamleitung hat Sie beauftragt, einige Features zu implementieren, um die Echtzeitüberwachung der App besser zu unterstützen. Die App muss Anforderungsdetails in der Konsole protokollieren. Für jede Anforderung sollen die Anforderungsmethode, der Pfad und der Antwortstatuscode protokolliert werden.

In dieser Übung erstellen Sie eine benutzerdefinierte Middlewarekomponente, die Anforderungsdetails in der Konsole protokolliert.

Hinzufügen benutzerdefinierter Middleware

Ändern Sie die vorhandene ASP.NET Core-App nun so, dass sie benutzerdefinierte Middleware enthält, die Anforderungsdetails in der Konsole protokolliert.

  1. Öffnen Sie die Datei Program.cs, wenn sie noch nicht geöffnet ist.

  2. Fügen Sie unmittelbar vor app.Run() den folgenden Code ein:

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

    Im obigen Code:

    • app.Use() fügt der Pipeline eine benutzerdefinierte Middlewarekomponente hinzu. Die Komponente akzeptiert ein HttpContext-Objekt und ein RequestDelegate-Objekt als Parameter.
    • Der Delegat schreibt die Anforderungsmethode, den Pfad und den Antwortstatuscode in die Konsole.
    • await next() ruft die nächste Middlewarekomponente in der Pipeline auf.

Testen der Änderungen

  1. Drücken Sie STRG+UMSCHALT+F5, um die App neu zu erstellen und zu starten.

  2. Wenn das Browserfenster geöffnet wird, beachten Sie, dass unter der Stamm-URL „Willkommen bei Contoso!“ angezeigt wird.

  3. Fügen Sie der URL /history hinzu, und drücken Sie die EINGABETASTE. Der Browser wird zur Seite /about umgeleitet.

  4. Drücken Sie in Visual Studio Code STRG+UMSCHALT+P, um die Befehlspalette zu öffnen. Suchen Sie nach dem folgenden Eintrag, und wählen Sie ihn aus: Debugging-Konsole: Fokus auf der Debugging-Konsolenansicht. So können Sie im unteren Bereich zur Registerkarte Debugging-Konsole wechseln. Beachten Sie die folgenden Zeilen:

    GET / 200
    GET /about 200
    

    In der Konsolenausgabe werden für jede Anforderung die Anforderungsmethode, der Pfad und der Antwortstatuscode angezeigt. In der ersten Zeile wird die Anforderung für die Stamm-URL und in der zweiten Zeile die Anforderung für die Seite /about angezeigt.

    Hinweis

    Ihr Browser kann auch /favicon.ico anfordern. Dies ist eine Standardanforderung für das Favicon einer Website und kann ignoriert werden.

  5. Lassen Sie die Anwendung für die nächste Übung geöffnet.

Ändern der Middlewarereihenfolge

Die App scheint zu funktionieren, aber es gibt ein Problem. Sie haben die Seite /history angefordert, aber die Konsolenausgabe zeigt sie nicht an. Dieses Verhalten liegt daran, dass die benutzerdefinierte Middlewarekomponente, die Anforderungsdetails protokolliert, nach der Middleware für den URL-Rewriter hinzugefügt wurde. Die Middleware für den URL-Rewriter leitet Anforderungen von /history an /about um und sendet die Antwort. Die benutzerdefinierte Middlewarekomponente sieht die Anforderung nicht. Korrigieren wir dies.

  1. Verschieben Sie die Zeile app.Use(), die Sie unmittelbar vor der Zeile app.UseRewriter() hinzugefügt haben.

    Die vollständige Datei Program.cs sollte wie folgt aussehen:

    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();
    

    Jetzt wird die benutzerdefinierte Middlewarekomponente vor der Middleware für den URL-Rewriter hinzugefügt. Die benutzerdefinierte Middlewarekomponente protokolliert die Anforderungsdetails, bevor die Middleware für den URL-Rewriter die Anforderung verarbeitet und umleitet.

  2. Starten Sie die App neu, und testen Sie sie wie zuvor. Diesmal sollte die Ausgabe der Debugging-Konsole die Anforderung für die Seite /history enthalten.

    GET / 200
    GET /history 200
    GET /about 200
    

    Die Konsolenausgabe zeigt nun die Anforderung für die Seite /history direkt vor der Umleitung zur Seite /about an.

Korrigieren des Statuscode

Die App ist fast fertig, aber es gibt ein weiteres Problem. Der Statuscode in der Konsolenausgabe ist immer 200, auch wenn die App die Anforderung umleitet. Der Statuscode für die /history-Anforderung sollte eine 302-Umleitung sein. Der Grund für dieses Verhalten ist ein weiteres Problem mit der Reihenfolge, in der die Middlewarekomponenten verarbeitet werden.

Die benutzerdefinierte Middlewarekomponente protokolliert die Details in der Konsole und ruft dann await next() zum Übergeben an die nächste Middlewarekomponente auf. Das Problem besteht darin, dass die Eigenschaft StatusCode des Response-Objekts festgelegt wird, nachdem die Terminal-Middlewarekomponente die Antwort gestartet hat. Ändern wir den Code, um dieses Problem zu beheben.

  1. Verschieben Sie im hinzugefügten Delegaten die Zeile Console.WriteLine() hinter die Zeile await next().

    Der aktualisierte Code sollte wie folgt aussehen:

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

    Nun protokolliert die benutzerdefinierte Middlewarekomponente die Anforderungsdetails, nachdem die Terminal-Middlewarekomponente den Antwortstatuscode festgelegt hat.

  2. Starten Sie die /history-Anforderung neu, und testen Sie sie erneut. Die Ausgabe der Debugging-Konsole sollte nun den richtigen Statuscode anzeigen.

    GET / 200
    GET /history 302
    GET /about 200