Neuerungen in ASP.NET Core 6.0

In diesem Artikel werden die wichtigsten Änderungen in ASP.NET Core 6.0 aufgezeigt und Links zur relevanten Dokumentation bereitgestellt.

ASP.NET Core MVC- und Razor-Verbesserungen

Minimale APIs

Minimal-APIs sind so entworfen, dass HTTP-APIs mit minimalen Abhängigkeiten erstellt werden. Sie eignen sich ideal für Microservices und Apps, die nur ein Minimum an Dateien, Funktionen und Abhängigkeiten in ASP.NET Core enthalten sollen. Weitere Informationen finden Sie unter:

SignalR

Tag für zeitintensive Aktivität für SignalR-Verbindungen

SignalR verwendet die neue Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity, um der Anforderungsaktivität ein http.long_running-Tag hinzuzufügen. IHttpActivityFeature.Activity wird von APM-Diensten wie Azure Monitor Application Insights verwendet, um SignalR-Anforderungen aus der Erstellung von Warnungen zu zeitintensiven Anforderungen zu filtern.

SignalR-Leistungsverbesserungen

  • Ordnen Sie HubCallerClients einmal pro Verbindung zu, anstatt bei jedem Aufruf der Hubmethode.
  • Die Abschlusszuordnung in SignalRDefaultHubDispatcher.Invoke wird vermieden. Der Zustand wird über Parameter an eine lokale statische Funktion übergeben, um eine Abschlusszuordnung zu vermeiden. Weitere Informationen finden Sie in diesem Pull Request in GitHub.
  • Beim Streaming vom Server zum Client wird eine einzige StreamItemMessage pro Stream statt pro Streamelement zugeordnet. Weitere Informationen finden Sie in diesem Pull Request in GitHub.

Razor-Compiler

Razor-Compiler auf die Verwendung von Quellgeneratoren aktualisiert

Der Razor-Compiler basiert jetzt auf C#-Quellgeneratoren. Quellgeneratoren werden während der Kompilierung ausgeführt und überprüfen, was kompiliert wird, um zusätzliche Dateien zu erzeugen, die zusammen mit dem Rest des Projekts kompiliert werden. Die Verwendung von Quellgeneratoren vereinfacht den Razor-Compiler und führt zu einer erheblichen Beschleunigung der Buildzeiten.

Razor-Compiler erzeugt keine separate Views-Assembly mehr

Der Razor-Compiler verwendete zuvor einen zweistufigen Kompilierungsprozess, bei dem eine separate Views-Assembly mit den in der App definierten generierten Ansichten und Seiten (.cshtml-Dateien) erzeugt wurde. Die generierten Typen waren öffentlich und unter dem AspNetCore-Namespace enthalten.

Der aktualisierte Razor-Compiler erstellt die Ansichts- und Seitentypen in der Hauptprojektassembly. Diese Typen werden jetzt standardmäßig als intern versiegelt im AspNetCoreGeneratedDocument-Namespace generiert. Diese Änderung verbessert die Buildleistung, ermöglicht die Bereitstellung einzelner Dateien und ermöglicht diesen Typen die Teilnahme an Hot Reload.

Weitere Informationen zu dieser Änderung finden Sie im zugehörigen Ankündigungsissue in GitHub.

ASP.NET Core-Leistung und API-Verbesserungen

Es wurden viele Änderungen vorgenommen, um die Zuordnungen zu reduzieren und die Leistung im gesamten Stapel zu verbessern:

Reduzierter Speicherbedarf für TLS-Verbindungen im Leerlauf

Bei zeitintensiven TLS-Verbindungen, bei denen Daten nur gelegentlich hin und her gesendet werden, haben wir den Speicherbedarf von ASP.NET Core-Apps in .NET 6 erheblich reduziert. So sollte die Skalierbarkeit von Szenarien wie WebSocket-Servern verbessert werden. Dies war aufgrund zahlreicher Verbesserungen in System.IO.Pipelines, SslStream und Kestrel möglich. In den folgenden Abschnitten werden einige der Verbesserungen beschrieben, die zur Verringerung des Speicherbedarfs beigetragen haben:

Verringern der Größe von System.IO.Pipelines.Pipe

Für jede hergestellte Verbindung werden zwei Pipes in Kestrel zugeordnet:

  • Die Transportschicht zur App für die Anforderung.
  • Die Anwendungsschicht zum Transport für die Antwort.

Durch Verringern der Größe von System.IO.Pipelines.Pipe von 368 auf 264 Byte (eine Verringerung um etwa 28,2 %) werden pro Verbindung 208 Byte eingespart (104 Byte pro Pipe).

Zusammenfassen von SocketSender im Pool

SocketSender-Objekte (Unterklassen von SocketAsyncEventArgs) umfassen zur Laufzeit etwa 350 Byte. Anstatt ein neues SocketSender-Objekt pro Verbindung zuzuordnen, können sie in einem Pool zusammengefasst werden. SocketSender-Objekte können in einem Pool zusammengefasst werden, weil Sendevorgänge in der Regel sehr schnell sind. Ein Pool reduziert den Mehraufwand pro Verbindung. Anstatt 350 Byte pro Verbindung zuzuordnen, werden nur 350 Byte pro IOQueue zugeordnet. Die Zuordnung erfolgt pro Warteschlange, um Konflikte zu vermeiden. Für unseren WebSocket-Server mit 5000 Verbindungen im Leerlauf wurde die Zuordnung von ca. 1,75 MB (350 Byte × 5000) auf eine Zuordnung von ca. 2,8 KB (350 Byte × 8) für SocketSender-Objekte reduziert.

Lesevorgänge von null Byte bei SslStream

Pufferlose Lesevorgänge sind eine Technik, die in ASP.NET Core verwendet wird, um das Mieten von Arbeitsspeicher aus dem Speicherpool zu vermeiden, wenn im Socket keine Daten verfügbar sind. Vor dieser Änderung erforderte unser WebSocket-Server mit 5.000 Verbindungen im Leerlauf ca. 200 MB ohne TLS im Vergleich zu ca. 800 MB mit TLS. Einige dieser Zuordnungen (4.000 pro Verbindung) rührten daher, dass Kestrel einen ArrayPool<T>-Puffer beibehalten musste, während auf den Abschluss der Lesevorgänge in SslStream gewartet wurde. Da sich diese Verbindungen im Leerlauf befanden, wurde keiner der Lesevorgänge abgeschlossen und der zugehörige Puffer an den ArrayPool zurückgegeben. Somit war der ArrayPool dazu gezwungen, mehr Speicher zu belegen. Die verbleibenden Zuordnungen lagen in SslStream selbst vor: ein Puffer von 4000 für TLS-Handshakes und ein Puffer von 32000 für normale Lesevorgänge. Wenn der Benutzer in .NET 6 einen Lesevorgang von 0 Byte in SslStream ausführt und keine Daten verfügbar sind, führt SslStream intern einen Lesevorgang von null Byte für den zugrunde liegenden umschlossenen Stream aus. Im besten Fall (Leerlaufverbindung) führen diese Änderungen zu Einsparungen von 40 KB pro Verbindung, während der Consumer (Kestrel) weiterhin über die Verfügbarkeit von Daten benachrichtigt werden kann, ohne dass ungenutzter Puffer beibehalten werden muss.

Null-Byte-Lesevorgänge mit PipeReader

Da pufferlose Lesevorgänge in SslStream unterstützt werden, wurde StreamPipeReader eine Option zum Durchführen von Lesevorgängen mit null Byte hinzugefügt. Dies ist der interne Typ zum Einpassen eines Stream in einen PipeReader. In Kestrel wird ein StreamPipeReader verwendet, um den zugrunde liegenden SslStream in einen PipeReader einzupassen. Daher war es erforderlich, diese Semantik für Lesevorgänge mit null Byte für den PipeReader verfügbar zu machen.

Über die folgende API kann jetzt ein PipeReader erstellt werden, der Lesevorgänge mit null Byte über einen zugrunde liegenden Stream unterstützt, der wiederum die Semantik von Lesevorgängen mit null Byte (z. B. SslStream, NetworkStream usw.) mithilfe der folgenden API unterstützt:

var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));

Entfernen von Bereichen aus dem SlabMemoryPool

Um die Fragmentierung des Heaps zu reduzieren, hat Kestrel ein Verfahren eingesetzt, bei dem Speicherbereiche von 128 KB als Teil des Speicherpools zugeordnet wurden. Die Bereiche wurden dann weiter in 4-KB-Blöcke unterteilt, die intern von Kestrel verwendet wurden. Die Bereiche mussten größer als 85 KB sein, um die Zuordnung auf dem großen Objektheap zu erzwingen und zu verhindern, dass die GC dieses Array verschiebt. Mit der Einführung der neuen GC-Generation (Pinned Object Heap, POH) ist es jedoch nicht mehr sinnvoll, Blöcke im Bereich zuzuordnen. Kestrel weist jetzt Blöcke direkt auf dem POH zu, sodass die Verwaltung des Speicherpools weniger komplex ist. Diese Änderung sollte die Durchführung zukünftiger Verbesserungen vereinfachen, z. B. das Verkleinern des von Kestrel verwendeten Speicherpools.

Unterstützung für IAsyncDisposable

IAsyncDisposable ist jetzt für Controller, Razor Pages und Ansichtskomponenten verfügbar. Asynchrone Versionen wurden den relevanten Schnittstellen in Factorys und Aktivatoren hinzugefügt:

  • Die neuen Methoden bieten eine Standardschnittstellenimplementierung, die an die synchrone Version delegiert und Dispose aufruft.
  • Die Implementierungen überschreiben die Standardimplementierung und verarbeiten das Entfernen von IAsyncDisposable-Implementierungen.
  • Wenn beide Schnittstellen implementiert werden, geben Implementierungen IAsyncDisposable gegenüber IDisposable den Vorzug.
  • Extendersteuerelemente müssen die neuen Methoden zum Unterstützen von IAsyncDisposable-Instanzen überschreiben.

IAsyncDisposable ist vorteilhaft bei der Arbeit mit folgenden Elementen:

  • Asynchrone Enumeratoren, z. B. in asynchronen Streams
  • Nicht verwaltete Ressourcen mit ressourcenintensiven E/A-Vorgängen, die freigegeben werden sollen

Verwenden Sie beim Implementieren dieser Schnittstelle die DisposeAsync-Methode, um Ressourcen freizugeben.

Stellen Sie sich einen Controller vor, der einen Utf8JsonWriter erstellt und verwendet. Utf8JsonWriter ist eine IAsyncDisposable-Ressource:

public class HomeController : Controller, IAsyncDisposable
{
    private Utf8JsonWriter? _jsonWriter;
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
        _jsonWriter = new Utf8JsonWriter(new MemoryStream());
    }

IAsyncDisposable muss DisposeAsync implementieren:

public async ValueTask DisposeAsync()
{
    if (_jsonWriter is not null)
    {
        await _jsonWriter.DisposeAsync();
    }

    _jsonWriter = null;
}

Vcpkg-Port für SignalR-C++-Client

Bei vcpkg handelt es sich um einen plattformübergreifenden Paket-Manager mit Befehlszeile für C- und C++-Bibliotheken. Kürzlich haben wir vcpkg einen Port hinzugefügt, um native CMake-Unterstützung für den SignalR-C++-Client hinzuzufügen. vcpkg funktioniert auch mit MSBuild.

Der SignalR-Client kann einem CMake-Projekt mit dem folgenden Codeausschnitt hinzugefügt werden, wenn vcpkg in der Toolkettendatei enthalten ist:

find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)

Mit dem obigen Codeausschnitt kann der SignalR-C++-Client #include verwenden und ohne zusätzliche Konfiguration in einem Projekt genutzt werden. Ein vollständiges Beispiel für eine C++-Anwendung, die den C++-Client von SignalR verwendet, finden Sie im Repository halter73/SignalR-Client-Cpp-Sample.

Blazor

Projektvorlagenänderungen

Für Blazor-Apps wurden mehrere Projektvorlagenänderungen vorgenommen, darunter die Verwendung der Datei Pages/_Layout.cshtml für Layout-Inhalte, die bei früheren Blazor Server-Apps in der Datei _Host.cshtml erschienen. Untersuchen Sie die Änderungen, indem Sie eine App aus einer 6.0-Projektvorlage erstellen oder auf die ASP.NET Core-Referenzquelle für die Projektvorlagen zugreifen:

Blazor WebAssembly-Unterstützung nativer Abhängigkeiten

Blazor WebAssembly-Apps können native Abhängigkeiten verwenden, die für die Ausführung in WebAssembly erstellt wurden. Weitere Informationen finden Sie unter ASP.NET Core Blazor WebAssembly: native Abhängigkeiten.

WebAssembly-AOT-Kompilierung (Ahead-of-Time) und erneute Runtimeverknüpfung

Blazor WebAssembly unterstützt die AOT-Kompilierung, mit der Sie Ihren .NET-Code direkt in WebAssembly kompilieren können. Die AOT-Kompilierung verbessert die Runtimeleistung, allerdings nimmt die Größe der App zu. Durch die Neuverknüpfung der WebAssembly-basierten .NET-Runtime wird nicht verwendeter Runtimecode gekürzt, um die Downloadgeschwindigkeit zu steigern. Weitere Informationen finden Sie unter AOT-Kompilierung (Ahead-of-Time) und Erneutes Verknüpfen der Runtime.

Beibehalten des vorab gerenderten Zustands

Blazor unterstützt das Beibehalten des Zustands auf einer vorab gerenderten Seite, sodass der Zustand nicht neu erstellt werden muss, wenn die App vollständig geladen ist. Weitere Informationen finden Sie unter Prerendering und Integrieren von Razor-Komponenten in ASP.NET Core.

Fehlergrenzen

Fehlergrenzen bieten eine gut geeignete Möglichkeit für die Behandlung von Ausnahmen auf Benutzeroberflächenebene. Weitere Informationen finden Sie unter Fehlerbehandlung in Blazor-Apps in ASP.NET Core.

SVG-Unterstützung

Das <foreignObject>-Element wird unterstützt, um beliebigen HTML-Code in einer SVG anzuzeigen. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Blazor Server-Unterstützung für die Bytearrayübertragung in JS-Interop

Blazor unterstützt optimierte Bytearray-JS-Interoperabilität, mit der sich die Codierung und Decodierung von Bytearrays in Base64 vermeiden lässt. Weitere Informationen finden Sie in den folgenden Ressourcen:

Verbesserungen von Abfragezeichenfolgen

Die Unterstützung für die Arbeit mit Abfragezeichenfolgen wurde verbessert. Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

Bindung zur Mehrfachauswahl

Die Bindung unterstützt die Auswahl mehrerer Optionen mit <input>-Elementen. Weitere Informationen finden Sie in den folgenden Ressourcen:

Steuern von <head>-Inhalten

Razor-Komponenten können den Inhalt des HTML-Elements <head> einer Seite ändern und so etwa den Titel der Seite (<title>-Element) festlegen und Metadaten (<meta>-Elemente) ändern. Weitere Informationen finden Sie unter Steuern des Inhalts von <head> in Blazor-Apps in ASP.NET Core.

Generieren von Angular- und React-Komponenten

Frameworkspezifische JavaScript-Komponenten werden aus Razor-Komponenten für Webframeworks, z. B. Angular oder React, generiert. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Rendern von Komponenten aus JavaScript

Razor-Komponenten werden dynamisch aus JavaScript für vorhandene JavaScript-Apps gerendert. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Benutzerdefinierte Elemente

Experimentelle Unterstützung ist für die Erstellung benutzerdefinierter Elemente verfügbar, die HTML-Standardschnittstellen verwenden. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Ableiten generischer Komponententypen von Vorgängerkomponenten

Eine Vorgängerkomponente kann mithilfe des neuen [CascadingTypeParameter]-Attributs einen Typparameter nach Namen an Nachfolger kaskadieren. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Dynamisch gerenderte Komponenten

Die neue integrierte DynamicComponent-Komponente wird verwendet, um Komponenten nach Typ zu rendern. Weitere Informationen finden Sie unter Dynamisch gerenderte Razor-Komponenten in ASP.NET Core.

Verbesserte Barrierefreiheit für Blazor

Verwenden Sie die neue FocusOnNavigate-Komponente, um den Fokus der Benutzeroberfläche auf Grundlage eines CSS-Selektors auf ein Element zu setzen, nachdem Sie von einer Seite zu einer anderen navigiert sind. Weitere Informationen finden Sie unter ASP.NET Core: Routing und Navigation in Blazor.

Unterstützung für benutzerdefinierte Ereignisargumente

Blazor unterstützt benutzerdefinierte Ereignisargumente, die es Ihnen ermöglichen, beliebige Daten mit benutzerdefinierten Ereignissen an .NET-Ereignishandler zu übergeben. Weitere Informationen finden Sie unter Ereignisbehandlung in Blazor in ASP.NET Core.

Erforderliche Parameter

Das neue [EditorRequired]-Attribut wird angewendet, um einen erforderlichen Komponentenparameter anzugeben. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

Kollokation von JavaScript-Dateien mit Seiten, Ansichten und Komponenten

Die Kollokation von JavaScript-Dateien für Seiten, Ansichten und Razor-Komponenten ist eine bequeme Möglichkeit, Skripts in einer App zu organisieren. Weitere Informationen finden Sie unter JavaScript-Interoperabilität von Blazor in ASP.NET Core (JS-Interoperabilität).

JavaScript-Initialisierer

JavaScript-Initialisierer führen Logik vor und nach dem Herunterladen einer Blazor-App aus. Weitere Informationen finden Sie unter JavaScript-Interoperabilität von Blazor in ASP.NET Core (JS-Interoperabilität).

Streamen von JavaScript-Interop

Blazor unterstützt jetzt das direkte Streamen von Daten zwischen .NET und JavaScript. Weitere Informationen finden Sie in den folgenden Ressourcen:

Generische Typeneinschränkungen

Generische Typparameter werden jetzt unterstützt. Weitere Informationen finden Sie unter Razor-Komponenten in ASP.NET Core.

WebAssembly-Bereitstellungslayout

Über ein Bereitstellungslayout können Downloads von Blazor WebAssembly-Apps in eingeschränkten Sicherheitsumgebungen aktiviert werden. Weitere Informationen finden Sie unter Bereitstellungslayout für in ASP.NET Core gehostete Blazor WebAssembly-Apps.

Neue Blazor-Artikel

Zusätzlich zu den in den vorherigen Abschnitten beschriebenen Blazor-Features sind neue Blazor-Artikel zu den folgenden Themen verfügbar:

Erstellen von Blazor Hybrid-Apps mit .NET MAUI, WPF und Windows Forms

Verwenden Sie Blazor Hybrid, um Desktop- und mobile native Clientframeworks mit .NET und Blazor zu kombinieren:

  • .NET Multi-platform App UI (.NET MAUI) ist ein plattformübergreifendes Framework zum Erstellen nativer mobiler und Desktop-Apps mit C# und XAML.
  • Blazor Hybrid-Apps können mit WPF-Frameworks (Windows Presentation Foundation) und Windows Forms-Frameworks erstellt werden.

Wichtig

Blazor Hybrid befindet sich in der Vorschauphase und sollte erst in der endgültigen Version in Produktions-Apps verwendet werden.

Weitere Informationen finden Sie in den folgenden Ressourcen:

Kestrel

HTTP/3 befindet sich derzeit in der Entwurfsphase und kann daher Änderungen unterliegen. Die HTTP/3-Unterstützung in ASP.NET Core wird nicht veröffentlicht. Es handelt sich um ein Vorschaufeature, das in .NET 6 enthalten ist.

Kestrel unterstützt nun HTTP/3. Weitere Informationen finden Sie unter Verwenden von HTTP/3 mit dem Kestrel-Webserver in ASP.NET Core und im Blogeintrag HTTP/3-Unterstützung in .NET 6.

Neue Kestrel-Protokollierungskategorien für die ausgewählte Protokollierung

Vor dieser Änderung war das Aktivieren der ausführlichen Protokollierung für Kestrel unerschwinglich, weil in Kestrel überall der Protokollierungskategoriename Microsoft.AspNetCore.Server.Kestrel gemeinsam verwendet wurde. Microsoft.AspNetCore.Server.Kestrel ist weiterhin verfügbar, aber die folgenden neuen Unterkategorien ermöglichen mehr Kontrolle über die Protokollierung:

  • Microsoft.AspNetCore.Server.Kestrel (aktuelle Kategorie): ApplicationError, ConnectionHeadResponseBodyWrite, ApplicationNeverCompleted, RequestBodyStart, RequestBodyDone, RequestBodyNotEntirelyRead, RequestBodyDrainTimedOut, ResponseMinimumDataRateNotSatisfied, InvalidResponseHeaderRemoved, HeartbeatSlow.
  • Microsoft.AspNetCore.Server.Kestrel.BadRequests: ConnectionBadRequest, RequestProcessingError, RequestBodyMinimumDataRateNotSatisfied.
  • Microsoft.AspNetCore.Server.Kestrel.Connections: ConnectionAccepted, ConnectionStart, ConnectionStop, ConnectionPause, ConnectionResume, ConnectionKeepAlive, ConnectionRejected, ConnectionDisconnect, NotAllConnectionsClosedGracefully, NotAllConnectionsAborted, ApplicationAbortedConnection.
  • Microsoft.AspNetCore.Server.Kestrel.Http2: Http2ConnectionError, Http2ConnectionClosing, Http2ConnectionClosed, Http2StreamError, Http2StreamResetAbort, HPackDecodingError, HPackEncodingError, Http2FrameReceived, Http2FrameSending, Http2MaxConcurrentStreamsReached.
  • Microsoft.AspNetCore.Server.Kestrel.Http3: Http3ConnectionError, Http3ConnectionClosing, Http3ConnectionClosed, Http3StreamAbort, Http3FrameReceived, Http3FrameSending.

Vorhandene Regeln funktionieren weiterhin, aber Sie können jetzt genauer auswählen, welche Regeln aktiviert werden sollen. Beispielsweise wird der Aufwand für den Einblick, der durch die Aktivierung der Debug-Protokollierung nur für fehlerhafte Anforderungen entsteht, erheblich reduziert und kann durch die folgende Konfiguration aktiviert werden:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
    }
  }

Die Protokollfilterung wendet Regeln mit dem längsten übereinstimmenden Kategoriepräfix an. Weitere Informationen finden Sie unter Anwendung von Filterregeln.

Ausgeben von KestrelServerOptions über das EventSource-Ereignis

Die KestrelEventSource gibt ein neues Ereignis aus, das den JSON-serialisierten KestrelServerOptions enthält, sofern mit der Ausführlichkeit EventLevel.LogAlways aktiviert. Dieses Ereignis erleichtert die Auswertung des Serververhaltens bei der Analyse gesammelter Ablaufverfolgungen. Der folgende JSON-Code ist ein Beispiel für die Ereignisnutzdaten:

{
  "AllowSynchronousIO": false,
  "AddServerHeader": true,
  "AllowAlternateSchemes": false,
  "AllowResponseHeaderCompression": true,
  "EnableAltSvc": false,
  "IsDevCertLoaded": true,
  "RequestHeaderEncodingSelector": "default",
  "ResponseHeaderEncodingSelector": "default",
  "Limits": {
    "KeepAliveTimeout": "00:02:10",
    "MaxConcurrentConnections": null,
    "MaxConcurrentUpgradedConnections": null,
    "MaxRequestBodySize": 30000000,
    "MaxRequestBufferSize": 1048576,
    "MaxRequestHeaderCount": 100,
    "MaxRequestHeadersTotalSize": 32768,
    "MaxRequestLineSize": 8192,
    "MaxResponseBufferSize": 65536,
    "MinRequestBodyDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
    "MinResponseDataRate": "Bytes per second: 240, Grace Period: 00:00:05",
    "RequestHeadersTimeout": "00:00:30",
    "Http2": {
      "MaxStreamsPerConnection": 100,
      "HeaderTableSize": 4096,
      "MaxFrameSize": 16384,
      "MaxRequestHeaderFieldSize": 16384,
      "InitialConnectionWindowSize": 131072,
      "InitialStreamWindowSize": 98304,
      "KeepAlivePingDelay": "10675199.02:48:05.4775807",
      "KeepAlivePingTimeout": "00:00:20"
    },
    "Http3": {
      "HeaderTableSize": 0,
      "MaxRequestHeaderFieldSize": 16384
    }
  },
  "ListenOptions": [
    {
      "Address": "https://127.0.0.1:7030",
      "IsTls": true,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "https://[::1]:7030",
      "IsTls": true,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "http://127.0.0.1:5030",
      "IsTls": false,
      "Protocols": "Http1AndHttp2"
    },
    {
      "Address": "http://[::1]:5030",
      "IsTls": false,
      "Protocols": "Http1AndHttp2"
    }
  ]
}

Neues DiagnosticSource-Ereignis für abgelehnte HTTP-Anforderungen

Kestrel gibt nun ein neues DiagnosticSource-Ereignis für HTTP-Anforderungen aus, die auf Serverebene abgelehnt werden. Vor dieser Änderung gab es keine Möglichkeit, diese abgelehnten Anforderungen zu beobachten. Das neue DiagnosticSource-Ereignis Microsoft.AspNetCore.Server.Kestrel.BadRequest enthält ein IBadRequestExceptionFeature, das verwendet werden kann, um den Grund für die Ablehnung der Anforderung zu prüfen.

using Microsoft.AspNetCore.Http.Features;
using System.Diagnostics;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var diagnosticSource = app.Services.GetRequiredService<DiagnosticListener>();
using var badRequestListener = new BadRequestEventListener(diagnosticSource,
    (badRequestExceptionFeature) =>
{
    app.Logger.LogError(badRequestExceptionFeature.Error, "Bad request received");
});
app.MapGet("/", () => "Hello world");

app.Run();

class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
{
    private readonly IDisposable _subscription;
    private readonly Action<IBadRequestExceptionFeature> _callback;

    public BadRequestEventListener(DiagnosticListener diagnosticListener,
                                   Action<IBadRequestExceptionFeature> callback)
    {
        _subscription = diagnosticListener.Subscribe(this!, IsEnabled);
        _callback = callback;
    }
    private static readonly Predicate<string> IsEnabled = (provider) => provider switch
    {
        "Microsoft.AspNetCore.Server.Kestrel.BadRequest" => true,
        _ => false
    };
    public void OnNext(KeyValuePair<string, object> pair)
    {
        if (pair.Value is IFeatureCollection featureCollection)
        {
            var badRequestFeature = featureCollection.Get<IBadRequestExceptionFeature>();

            if (badRequestFeature is not null)
            {
                _callback(badRequestFeature);
            }
        }
    }
    public void OnError(Exception error) { }
    public void OnCompleted() { }
    public virtual void Dispose() => _subscription.Dispose();
}

Weitere Informationen finden Sie unter Protokollierung und Diagnose in Kestrel.

Erstellen eines ConnectionContext aus einem akzeptieren Socket

Die neue SocketConnectionContextFactory ermöglicht das Erstellen eines ConnectionContext aus einem akzeptierten Socket. So kann eine benutzerdefinierte, socketbasierte IConnectionListenerFactory erstellt werden, ohne dass der gesamte Leistungsaufwand und das Pooling in SocketConnection verloren gehen.

In diesem Beispiel für eine benutzerdefinierte IConnectionListenerFactory wird die Verwendung dieser SocketConnectionContextFactory veranschaulicht.

Kestrel ist das Standardstartprofil für Visual Studio

Das Standardstartprofil für alle neuen dotnet-Webprojekte ist Kestrel. Der Startvorgang von Kestrel ist deutlich schneller und führt zu einer reaktionsschnelleren Umgebung beim Entwickeln von Apps.

IIS Express ist weiterhin als Startprofil für Szenarien wie die Windows-Authentifizierung oder die Portfreigabe verfügbar.

Localhost-Ports für Kestrel sind zufällig

Weitere Informationen finden Sie unter Durch Vorlagen generierte Ports für Kestrel.

Authentifizierung und Autorisierung

Authentifizierungsserver

In .NET 3 bis .NET 5 wurde IdentityServer4 als Teil unserer Vorlage verwendet, um das Ausstellen von JWT-Token für SPA und Blazor-Anwendungen zu unterstützen. Die Vorlagen verwenden jetzt den Duende Identity Server.

Wenn Sie die Identitätsmodelle erweitern und vorhandene Projekte aktualisieren, müssen Sie die Namespaces im Code von IdentityServer4.IdentityServer auf Duende.IdentityServer aktualisieren und die zugehörigen Migrationsanleitungen befolgen.

Das Lizenzmodell für Duende Identity Server wurde in eine reziproke Lizenz geändert, für die bei kommerziellem Einsatz in der Produktion möglicherweise Lizenzgebühren anfallen. Weitere Informationen finden Sie auf der Duende-Lizenzseite.

Verzögerte Clientzertifikataushandlung

Entwickler können sich jetzt für die Verwendung der verzögerten Clientzertifikataushandlung entscheiden, indem sie ClientCertificateMode.DelayCertificate in den HttpsConnectionAdapterOptions angeben. Dies funktioniert nur bei HTTP/1.1-Verbindungen, weil HTTP/2 die verzögerte Neuverhandlung von Zertifikaten verbietet. Der Aufrufer dieser API muss den Anforderungstext puffern, bevor er das Clientzertifikat anfordert:

using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.AspNetCore.WebUtilities;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseKestrel(options =>
{
    options.ConfigureHttpsDefaults(adapterOptions =>
    {
        adapterOptions.ClientCertificateMode = ClientCertificateMode.DelayCertificate;
    });
});

var app = builder.Build();
app.Use(async (context, next) =>
{
    bool desiredState = GetDesiredState();
    // Check if your desired criteria is met
    if (desiredState)
    {
        // Buffer the request body
        context.Request.EnableBuffering();
        var body = context.Request.Body;
        await body.DrainAsync(context.RequestAborted);
        body.Position = 0;

        // Request client certificate
        var cert = await context.Connection.GetClientCertificateAsync();

        //  Disable buffering on future requests if the client doesn't provide a cert
    }
    await next(context);
});


app.MapGet("/", () => "Hello World!");
app.Run();

Der gleitende Ablauf der Authentifizierung von Cookie kann jetzt mithilfe des neuen OnCheckSlidingExpirationangepasst oder unterdrückt werden. Dieses Ereignis kann beispielsweise von einer Single-Page-Webanwendung verwendet werden, die den Server regelmäßig pingen muss, ohne die Authentifizierungssitzung zu beeinträchtigen.

Sonstiges

Erneut laden

Nehmen Sie schnell Benutzeroberflächen- und Codeupdates für ausgeführte Apps vor, ohne den App-Zustand zu verlieren. So profitieren Sie von einer schnelleren und produktiveren Entwicklerumgebung, die Hot Reload verwendet. Weitere Informationen finden Sie unter Unterstützung von .NET Hot Reload für ASP.NET Core und Update on .NET Hot Reload progress and Visual Studio 2022 Highlights (Update zum Fortschritt von .NET Hot Reload und Highlights von Visual Studio 2022).

Verbesserte SPA-Vorlagen (Single-Page-Webanwendungen)

Die ASP.NET Core-Projektvorlagen wurden für Angular und React aktualisiert und verwenden jetzt ein verbessertes Muster für Single-Page-Webanwendungen, das flexibler und stärker an gängigen Mustern für die moderne Front-End-Webentwicklung ausgerichtet ist.

Zuvor verwendete die ASP.NET Core-Vorlage für Angular und React während der Entwicklung spezielle Middleware, um den Entwicklungsserver für das Front-End-Framework zu starten und dann Anforderungen von ASP.NET Core über einen Proxy an den Entwicklungsserver zu senden. Die Logik zum Starten des Front-End-Entwicklungsservers war spezifisch für die Befehlszeilenschnittstelle des entsprechenden Front-End-Frameworks. Zur Unterstützung zusätzlicher Front-End-Frameworks mit diesem Muster musste ASP.NET Core zusätzliche Logik hinzugefügt werden.

Die aktualisierten ASP.NET Core-Vorlagen für Angular und React in .NET 6 drehen diese Anordnung um und nutzen die integrierte Proxyunterstützung auf den Entwicklungsservern der meisten modernen Front-End-Frameworks. Beim Start der ASP.NET Core-App wird der Front-End-Entwicklungsserver wie zuvor gestartet, aber der Entwicklungsserver ist so konfiguriert, dass Anforderungen per Proxy an den ASP.NET Core-Back-End-Prozess gesendet werden. Die ganze Front-End-spezifische Konfiguration zum Einrichten des Proxys ist Teil der App und gehört nicht zu ASP.NET Core. Das Einrichten von ASP.NET Core-Projekten für die Arbeit mit anderen Front-End-Frameworks ist jetzt einfach: Richten Sie den Front-End-Entwicklungsserver für das ausgewählte Framework so ein, dass er über einen Proxy mit dem ASP.NET Core-Back-End kommuniziert und dabei das in den Angular- und React-Vorlagen eingerichtete Muster verwendet.

Der Startcode für die ASP.NET Core-App benötigt keine für Single-Page-Apps spezifische Logik mehr. Die Logik zum Starten des Front-End-Entwicklungsservers während der Entwicklung wird zur Laufzeit durch das neue Microsoft.AspNetCore.SpaProxy-Paket in die App injiziert. Das Fallbackrouting erfolgt über Endpunktrouting anstelle von SPA-spezifischer Middleware.

Vorlagen, die diesem Muster folgen, können weiterhin als einzelnes Projekt in Visual Studio oder über dotnet run in der Befehlszeile ausgeführt werden. Bei Veröffentlichung der App wird der Front-End-Code wie zuvor im Ordner ClientApp im Webstamm der ASP.NET Core-Host-App erstellt und gesammelt und in Form von statischen Dateien bereitgestellt. In der Vorlage enthaltene Skripts konfigurieren den Front-End-Entwicklungsserver für die Verwendung von HTTPS anhand des ASP.NET Core-Entwicklungszertifikats.

Entwurf der HTTP/3-Unterstützung in .NET 6

HTTP/3 befindet sich derzeit in der Entwurfsphase und kann daher Änderungen unterliegen. Die HTTP/3-Unterstützung in ASP.NET Core wird nicht veröffentlicht. Es handelt sich um ein Vorschaufeature, das in .NET 6 enthalten ist.

Weitere Informationen finden Sie im Blogeintrag zur HTTP/3-Unterstützung in .NET 6.

Anmerkungen zu Nullable-Verweistypen

Auf Teile des ASP.NET Core 6.0-Quellcodes wurden Anmerkungen zur NULL-Zulässigkeit angewendet.

Durch die Verwendung des neuen Nullable-Features in C# 8 kann ASP.NET Core zur Kompilierzeit zusätzliche Sicherheit bei der Behandlung von Verweistypen bereitstellen. Dazu gehört beispielsweise der Schutz vor null-Verweisausnahmen. Bei Projekten, für die die Verwendung von Nullable-Anmerkungen aktiviert ist, werden möglicherweise zur Buildzeit neue Warnungen von ASP.NET Core-APIs angezeigt.

Fügen Sie Projektdateien die folgende Eigenschaft hinzu, um Nullable-Verweistypen zu aktivieren:

<PropertyGroup>
    <Nullable>enable</Nullable>
</PropertyGroup>

Weitere Informationen finden Sie unter Nullable-Verweistypen.

Quellcodeanalyse

Es wurden mehrere Analysetools für die .NET-Compilerplattform hinzugefügt, mit denen Anwendungscode auf Probleme wie falsche Middlewarekonfiguration oder -reihenfolge, Routingkonflikte usw. untersucht wird. Weitere Informationen finden Sie unter Codeanalyse in ASP.NET Core-Apps.

Verbesserungen an Web-App-Vorlagen

Für eine Web-App-Vorlage gilt Folgendes:

  • Sie verwendet das neue minimale Hostingmodell.
  • Sie führt zu einer erheblich geringeren Anzahl der Dateien und Codezeilen, die zum Erstellen einer App erforderlich sind. Beispielsweise erstellt die leere ASP.NET Core-Web-App eine C#-Datei mit vier Codezeilen und ist eine vollständige App.
  • Sie vereinheitlicht Startup.cs und Program.cs in einer einzigen Program.cs-Datei.
  • Sie verwendet Anweisungen der obersten Ebene, um den für eine App erforderlichen Code zu minimieren.
  • Sie verwendet globale using-Anweisungen, um die Anzahl der erforderlichen Zeilen in einer using-Anweisung zu beseitigen oder zu minimieren.

Durch Vorlagen generierte Ports für Kestrel

Während der Projekterstellung werden zufällige Ports zur Verwendung durch den Kestrel-Webserver zugewiesen. Zufällige Ports tragen dazu bei, einen Portkonflikt zu vermeiden, wenn mehrere Projekte auf demselben Computer ausgeführt werden.

Beim Erstellen eines Projekts werden ein zufälliger HTTP-Port zwischen 5000 und 5300 und ein zufälliger HTTPS-Port zwischen 7000 und 7300 in der generierten Datei Properties/launchSettings.json angegeben. Die Ports können in der Datei Properties/launchSettings.json geändert werden. Wenn kein Port angegeben ist, verwendet Kestrel standardmäßig die Ports HTTP 5000 und HTTPS 5001. Weitere Informationen finden Sie unter Konfigurieren von Endpunkten für den Kestrel-Webserver von ASP.NET Core.

Neue Protokollierungseinstellungen

Die folgenden Änderungen wurden sowohl an appsettings.json als auch an appsettings.Development.json vorgenommen:

- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"

Die Änderung von "Microsoft": "Warning" in "Microsoft.AspNetCore": "Warning" führt dazu, dass alle Informationsmeldungen aus dem Microsoft-Namespace mit Ausnahme vonMicrosoft.AspNetCore protokolliert werden. Beispielsweise wird Microsoft.EntityFrameworkCore jetzt auf der Informationsebene protokolliert.

Middleware für Entwicklerausnahmeseite automatisch hinzugefügt

In der Entwicklungsumgebung wird die DeveloperExceptionPageMiddleware standardmäßig hinzugefügt. Es ist nicht mehr erforderlich, Webbenutzeroberflächen-Apps den folgenden Code hinzuzufügen:

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

Unterstützung für Latin1-codierte Anforderungsheader in HttpSysServer

HttpSysServer unterstützt jetzt das Decodieren von Anforderungsheadern, die mit Latin1 codiert sind, indem die UseLatin1RequestHeaders-Eigenschaft in den HttpSysOptions auf true festgelegt wird:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

ASP.NET Core-Modulprotokolle enthalten Zeitstempel und PID

Die erweiterten Diagnoseprotokolle des ASP.NET Core-Moduls (ANCM) für IIS enthalten Zeitstempel und die PID des Prozesses, der die Protokolle ausgibt. Die Protokollierung von Zeitstempeln und PID erleichtert die Diagnose von Problemen mit überlappenden Prozessneustarts in IIS, wenn mehrere IIS-Workerprozesse ausgeführt werden.

Die resultierenden Protokolle ähneln jetzt der nachstehenden Beispielausgabe:

[2021-07-28T19:23:44.076Z, PID: 11020] [aspnetcorev2.dll] Initializing logs for 'C:\<path>\aspnetcorev2.dll'. Process Id: 11020. File Version: 16.0.21209.0. Description: IIS ASP.NET Core Module V2. Commit: 96475a2acdf50d7599ba8e96583fa73efbe27912.
[2021-07-28T19:23:44.079Z, PID: 11020] [aspnetcorev2.dll] Resolving hostfxr parameters for application: '.\InProcessWebSite.exe' arguments: '' path: 'C:\Temp\e86ac4e9ced24bb6bacf1a9415e70753\'
[2021-07-28T19:23:44.080Z, PID: 11020] [aspnetcorev2.dll] Known dotnet.exe location: ''

Konfigurierbare Größe für ungenutzten eingehenden Puffer für IIS

Der IIS-Server hat zuvor nur 64 KiB von nicht verwendeten Anforderungstexten gepuffert. Die 64-KiB-Pufferung führte dazu, dass Lesevorgänge auf diese maximale Größe beschränkt wurden. Dies wirkte sich bei umfangreichen eingehenden Texten wie Uploads auf die Leistung aus. In .NET 6 ändert sich die Standardpuffergröße von 64 KiB in 1 MiB, wodurch sich der Durchsatz für große Uploads verbessern sollte. In unseren Tests dauert ein 700-MiB-Upload, der bisher 9 Sekunden in Anspruch genommen hat, jetzt nur noch 2,5 Sekunden.

Der Nachteil eines größeren Puffers besteht in einem erhöhten Arbeitsspeicherverbrauch pro Anforderung, wenn die App nicht schnell aus dem Anforderungstext liest. Neben der geänderten Standardpuffergröße ist es daher jetzt möglich, die Puffergröße zu konfigurieren, sodass Apps die Puffergröße basierend auf der Workload konfigurieren können.

Taghilfselemente für Ansichtskomponenten

Stellen Sie sich eine Ansichtskomponente mit einem optionalen Parameter vor, wie im folgenden Code gezeigt:

class MyViewComponent
{
    IViewComponentResult Invoke(bool showSomething = false) { ... }
}

Mit ASP.NET Core 6 kann das Taghilfselement aufgerufen werden, ohne einen Wert für den Parameter showSomething angeben zu müssen:

<vc:my />

Angular-Vorlage auf Angular 12 aktualisiert

Die ASP.NET Core 6.0-Vorlage für Angular verwendet jetzt Angular 12.

Die React-Vorlage wurde auf React 17 aktualisiert.

Konfigurierbarer Pufferschwellenwert vor dem Schreiben auf den Datenträger in Json.NET-Ausgabeformatierer

Hinweis: Es wird empfohlen, den System.Text.Json-Ausgabeformatierer zu verwenden, es sei denn, das Newtonsoft.Json-Serialisierungsmodul ist aus Kompatibilitätsgründen erforderlich. Das System.Text.Json-Serialisierungsmodul ist vollständig async und funktioniert effizient für größere Nutzdaten.

Der Newtonsoft.Json-Ausgabeformatierer puffert Antworten von bis zu 32 KiB standardmäßig im Arbeitsspeicher, bevor auf den Datenträger gepuffert wird. Dadurch soll die Ausführung synchroner E/A vermieden werden, die zu anderen Nebeneffekten führen kann, z. B. zu Threadstarvation und Anwendungsdeadlocks. Wenn die Antwort jedoch mehr als 32 KiB umfasst, treten beträchtliche Datenträger-E/A-Vorgänge auf. Der Arbeitsspeicherschwellenwert kann jetzt vor dem Puffern auf den Datenträger über die Eigenschaft MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold konfiguriert werden:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages()
            .AddNewtonsoftJson(options =>
            { 
                options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
            });

var app = builder.Build();

Weitere Informationen finden Sie in diesem Pull Request in GitHub und in der Datei NewtonsoftJsonOutputFormatterTest.cs.

Schnelleres Abrufen und Festlegen für HTTP-Header

Es wurden neue APIs hinzugefügt, um alle in Microsoft.Net.Http.Headers.HeaderNames verfügbaren allgemeinen Header als Eigenschaften im IHeaderDictionary verfügbar zu machen und so die API benutzerfreundlicher zu gestalten. Beispielsweise ruft die Inlinemiddleware im folgenden Code sowohl Anforderungs- als auch Antwortheader mithilfe der neuen APIs ab und legt sie fest:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Use(async (context, next) =>
{
    var hostHeader = context.Request.Headers.Host;
    app.Logger.LogInformation("Host header: {host}", hostHeader);
    context.Response.Headers.XPoweredBy = "ASP.NET Core 6.0";
    await next.Invoke(context);
    var dateHeader = context.Response.Headers.Date;
    app.Logger.LogInformation("Response date: {date}", dateHeader);
});

app.Run();

Bei implementierten Headern werden die Get- und Set-Zugriffsmethoden implementiert, indem direkt zum Feld gewechselt und das Lookup umgangen wird. Bei nicht implementierten Headern können die Zugriffsmethoden das anfängliche Lookup für implementierte Header umgehen und das Dictionary<string, StringValues>-Lookup direkt ausführen. Das Vermeiden des Lookups führt in beiden Szenarien zu einem schnelleren Zugriff.

Asynchrones Streaming

ASP.NET Core unterstützt jetzt das asynchrone Streaming von Controlleraktionen und Antworten vom JSON-Formatierer. Durch die Rückgabe von IAsyncEnumerable aus einer Aktion wird der Antwortinhalt nicht mehr im Arbeitsspeicher gepuffert, bevor er gesendet wird. Durch das Nichtpuffern wird die Speicherauslastung reduziert, wenn große Datasets zurückgegeben werden, die asynchron aufgezählt werden können.

Beachten Sie, dass Entity Framework Core Implementierungen von IAsyncEnumerable zum Abfragen der Datenbank bereitstellt. Durch die verbesserte Unterstützung für IAsyncEnumerable in ASP.NET Core in .NET 6 kann EF Core mit ASP.NET Core effizienter genutzt werden. Beispielsweise puffert der folgende Code die Produktdaten nicht mehr im Arbeitsspeicher, bevor die Antwort gesendet wird:

public IActionResult GetMovies()
{
    return Ok(_context.Movie);
}

Bei Verwendung des verzögerten Ladens in EF Core kann dieses neue Verhalten aufgrund der gleichzeitigen Abfrageausführung während der Datenenumeration jedoch zu Fehlern führen. Apps können zum vorherigen Verhalten zurückkehren, indem sie die Daten puffern:

public async Task<IActionResult> GetMovies2()
{
    return Ok(await _context.Movie.ToListAsync());
}

Weitere Informationen zu dieser Verhaltensänderung finden Sie in der entsprechenden Ankündigung.

Middleware für die HTTP-Protokollierung

Die HTTP-Protokollierung ist eine neue integrierte Middleware, die Informationen zu HTTP-Anforderungen und HTTP-Antworten protokolliert, einschließlich der Header und des gesamten Textkörpers:

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();
app.UseHttpLogging();

app.MapGet("/", () => "Hello World!");

app.Run();

Durch die Navigation zu / mit dem vorherigen Code werden Informationen protokolliert, die der folgenden Ausgabe ähneln:

info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[1]
      Request:
      Protocol: HTTP/2
      Method: GET
      Scheme: https
      PathBase: 
      Path: /
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cache-Control: max-age=0
      Connection: close
      Cookie: [Redacted]
      Host: localhost:44372
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30
      sec-ch-ua: [Redacted]
      sec-ch-ua-mobile: [Redacted]
      sec-ch-ua-platform: [Redacted]
      upgrade-insecure-requests: [Redacted]
      sec-fetch-site: [Redacted]
      sec-fetch-mode: [Redacted]
      sec-fetch-user: [Redacted]
      sec-fetch-dest: [Redacted]
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      Response:
      StatusCode: 200
      Content-Type: text/plain; charset=utf-8

Die vorherige Ausgabe wurde mit der folgenden Datei appsettings.Development.json aktiviert:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
    }
  }
}

Die HTTP-Protokollierung enthält Protokolle zu:

  • HTTP-Anforderungsinformationen
  • Allgemeine Eigenschaften
  • Header
  • Text
  • HTTP-Antwortinformationen

Um die Middleware für die HTTP-Protokollierung zu konfigurieren, geben Sie HttpLoggingOptions an:

using Microsoft.AspNetCore.HttpLogging;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpLogging(logging =>
{
    // Customize HTTP logging.
    logging.LoggingFields = HttpLoggingFields.All;
    logging.RequestHeaders.Add("My-Request-Header");
    logging.ResponseHeaders.Add("My-Response-Header");
    logging.MediaTypeOptions.AddText("application/javascript");
    logging.RequestBodyLogLimit = 4096;
    logging.ResponseBodyLogLimit = 4096;
});

var app = builder.Build();
app.UseHttpLogging();

app.MapGet("/", () => "Hello World!");

app.Run();

IConnectionSocketFeature

Das IConnectionSocketFeature-Anforderungsfeature ermöglicht den Zugriff auf den zugrunde liegenden akzeptierten Socket, der der aktuellen Anforderung zugeordnet ist. Er ist über die FeatureCollection im HttpContext zugänglich.

Die folgende App legt beispielsweise die Eigenschaft LingerState für den akzeptierten Socket fest:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureEndpointDefaults(listenOptions => listenOptions.Use((connection, next) =>
    {
        var socketFeature = connection.Features.Get<IConnectionSocketFeature>();
        socketFeature.Socket.LingerState = new LingerOption(true, seconds: 10);
        return next();
    }));
});
var app = builder.Build();
app.MapGet("/", (Func<string>)(() => "Hello world"));
await app.RunAsync();

Einschränkungen generischer Typen in Razor

Beim Definieren generischer Typparameter in Razor über die @typeparam-Anweisung können Einschränkungen generischer Typen jetzt mithilfe der C#-Standardsyntax angegeben werden:

Kleinere SignalR-, Blazor Server- und MessagePack-Skripts

Die SignalR-, MessagePack- und Blazor Server-Skripts sind jetzt deutlich kleiner und ermöglichen kleinere Downloads, weniger JavaScript-Analyse und -Kompilierung durch den Browser und schnelleres Starten. Die Größenreduzierungen:

  • signalr.js: 70 %
  • blazor.server.js: 45 %

Die kleineren Skripts sind das Ergebnis eines Communitybeitrags von Ben Adams. Weitere Informationen zu den Details der Größenreduzierung finden Sie in Bens Pull Request in GitHub.

Aktivieren von Redis-Profilerstellungssitzungen

Durch einen Communitybeitrag von Gabriel Lucaci wird eine Redis-Profilerstellungssitzung mit Microsoft.Extensions.Caching.StackExchangeRedis ermöglicht:

using StackExchange.Redis.Profiling;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddStackExchangeRedisCache(options =>
{
    options.ProfilingSession = () => new ProfilingSession();
});

Weitere Informationen finden Sie unter StackExchange.Redis-Profilerstellung.

Schattenkopien in IIS

Dem ASP.NET Core-Modul (ANCM) für IIS wurde ein experimentelles Feature hinzugefügt, damit Schattenkopien von Anwendungsassemblys unterstützt werden. Derzeit sperrt .NET Anwendungsbinärdateien bei der Ausführung unter Windows, sodass Binärdateien während der App-Ausführung nicht ersetzt werden können. Es wird zwar weiterhin empfohlen, eine App-Offlinedatei zu verwenden, aber es gibt bestimmte Szenarien (z. B. FTP-Bereitstellungen), in denen dies nicht möglich ist.

Aktivieren Sie in solchen Szenarien Schattenkopien, indem Sie die ASP.NET Core-Modulhandlereinstellungen anpassen. In den meisten Fällen verfügen ASP.NET Core-Apps nicht über eine web.config, die in der Quellcodeverwaltung eingecheckt ist und geändert werden kann. In ASP.NET Core wird die web.config normalerweise vom SDK generiert. Das folgende Beispiel für eine web.config kann für den Einstieg verwendet werden:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->

  <system.webServer>
    <handlers>
      <remove name="aspNetCore"/>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
      <handlerSettings>
        <handlerSetting name="experimentalEnableShadowCopy" value="true" />
        <handlerSetting name="shadowCopyDirectory" value="../ShadowCopyDirectory/" />
        <!-- Only enable handler logging if you encounter issues-->
        <!--<handlerSetting name="debugFile" value=".\logs\aspnetcore-debug.log" />-->
        <!--<handlerSetting name="debugLevel" value="FILE,TRACE" />-->
      </handlerSettings>
    </aspNetCore>
  </system.webServer>
</configuration>

Schattenkopien in IIS sind ein experimentelles Feature, das nicht garantiert in ASP.NET Core integriert wird. Bitte hinterlassen Sie Feedback zu IIS-Schattenkopien in diesem GitHub-Issue.

Zusätzliche Ressourcen