Delen via


Wat is er nieuw in ASP.NET Core in .NET 6

In dit artikel worden de belangrijkste wijzigingen in ASP.NET Core in .NET 6 beschreven met koppelingen naar relevante documentatie.

Verbeteringen in ASP.NET Core MVC en Razor

Minimale APIs

Minimale API's zijn ontworpen om HTTP-API's te maken met minimale afhankelijkheden. Ze zijn ideaal voor microservices en apps die alleen de minimale bestanden, functies en afhankelijkheden in ASP.NET Core willen opnemen. Zie voor meer informatie:

SignalR

Langlopende activiteitstag voor SignalR verbindingen

SignalR gebruikt de nieuwe Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity om een http.long_running tag toe te voegen aan de aanvraagactiviteit. IHttpActivityFeature.Activity wordt gebruikt door APM-services zoals Azure Monitor Application Insights om verzoeken te filteren en te voorkomen dat er langdurige verzoekwaarschuwingen worden gemaakt.

SignalR Prestatieverbeteringen

  • Wijs HubCallerClients eenmaal per verbinding toe in plaats van elke hubmethodeaanroep.
  • Vermijd sluitingstoewijzing in SignalRDefaultHubDispatcher.Invoke. Status wordt doorgegeven aan een lokale statische functie via parameters om een sluitingstoewijzing te voorkomen. Zie deze GitHub-pull-aanvraagvoor meer informatie.
  • Wijs één StreamItemMessage per stream toe in plaats van per streamitem in server-naar-clientstreaming. Zie deze GitHub-pull-aanvraagvoor meer informatie.

Razor Compiler

Razor compiler bijgewerkt om brongeneratoren te gebruiken

De Razor compiler is nu gebaseerd op C#-brongeneratoren. Brongeneratoren worden uitgevoerd tijdens het compileren en inspecteren wat er wordt gecompileerd om extra bestanden te produceren die samen met de rest van het project worden gecompileerd. Het gebruik van brongeneratoren vereenvoudigt de Razor compiler en versnelt de buildtijden aanzienlijk.

Razor compiler produceert geen afzonderlijke weergavenassembly meer

De Razor compiler maakte eerder gebruik van een compilatieproces in twee stappen dat een afzonderlijke Views-assembly produceerde die de gegenereerde weergaven en pagina's (.cshtml bestanden) bevatte die in de app zijn gedefinieerd. De gegenereerde typen waren openbaar en onder de AspNetCore naamruimte.

De bijgewerkte Razor compiler bouwt de weergaven en paginatypen op in de hoofdprojectassembly. Deze typen worden nu standaard gegenereerd als intern verzegeld in de AspNetCoreGeneratedDocument naamruimte. Deze wijziging verbetert de buildprestaties, maakt implementatie van één bestand mogelijk en stelt deze typen in staat om deel te nemen aan Hot Reload.

Zie de betreffende aankondiging op GitHub voor meer informatie over deze wijziging.

ASP.NET Belangrijkste prestatie- en API-verbeteringen

Er zijn veel wijzigingen aangebracht om toewijzingen te verminderen en de prestaties in de stack te verbeteren:

Verminderde geheugenvoetafdruk voor niet-actieve TLS-verbindingen

Voor langlopende TLS-verbindingen waarbij gegevens slechts af en toe heen en weer worden verzonden, hebben we de geheugenvoetafdruk van ASP.NET Core-apps in .NET 6 aanzienlijk verminderd. Dit moet helpen de schaalbaarheid van scenario's zoals WebSocket-servers te verbeteren. Dit was mogelijk vanwege talloze verbeteringen in System.IO.Pipelines, SslStreamen Kestrel. In de volgende secties worden enkele van de verbeteringen beschreven die hebben bijgedragen aan de verminderde geheugenvoetafdruk:

Verminder de grootte van System.IO.Pipelines.Pipe

Voor elke verbinding die tot stand is gebracht, worden er twee pijpen toegewezen in Kestrel:

  • De transportlaag voor het verzoek naar de app.
  • De toepassingslaag die naar het transport voor de respons leidt.

Door de grootte van System.IO.Pipelines.Pipe van 368 bytes naar 264 bytes te verkleinen (ongeveer 28,2%% reductie), wordt 208 bytes per verbinding bespaard (104 bytes per Pipe).

Pool SocketSender

SocketSender objecten (die subklassen van SocketAsyncEventArgs zijn) zijn ongeveer 350 bytes tijdens de uitvoertijd. In plaats van een nieuw SocketSender object per verbinding toe te wijzen, kunnen ze worden gegroepeerd. SocketSender objecten kunnen worden gegroepeerd omdat verzendingen meestal zeer snel zijn. Pooling vermindert de overhead per verbinding. In plaats van 350 bytes per verbinding toe te wijzen, worden er slechts 350 bytes per IOQueue toegewezen. Toewijzing wordt uitgevoerd per wachtrij om conflicten te voorkomen. Onze WebSocket-server met 5000 niet-actieve verbindingen ging van het toewijzen van ~1,75 MB (350 bytes * 5000) tot het toewijzen van ~2,8 kb (350 bytes * 8) voor SocketSender objecten.

Nul bytes lezen met SslStream

Bufferloze leesbewerkingen zijn een techniek die wordt gebruikt in ASP.NET Core om te voorkomen dat geheugen uit de geheugengroep wordt gehuurd als er geen gegevens beschikbaar zijn op de socket. Vóór deze wijziging vereist onze WebSocket-server met 5000 niet-actieve verbindingen ~200 MB zonder TLS in vergelijking met ~800 MB met TLS. Sommige van deze toewijzingen (4k per verbinding) moesten Kestrel in een ArrayPool<T> buffer blijven terwijl ze wachten totdat de leesbewerkingen op SslStream zijn voltooid. Gezien het feit dat deze verbindingen niet actief waren, werd geen enkele leesbewerking voltooid en werden hun buffers niet geretourneerd aan de ArrayPool, waardoor de ArrayPool gedwongen werd meer geheugen toe te wijzen. De resterende toewijzingen waren op SslStream zelf: een 4k-buffer voor TLS-handshakes en een 32k-buffer voor normale lezingen. Wanneer de gebruiker in .NET 6 een nul-byte-leesbewerking uitvoert op SslStream en er geen gegevens beschikbaar zijn, voert SslStream intern een nul-byte-leesbewerking uit op de onderliggende omgevouwen stream. In het beste geval (niet-actieve verbinding) leiden deze wijzigingen tot een besparing van 40 kB per verbinding, terwijl de consument (Kestrel) nog steeds op de hoogte kan worden gesteld wanneer gegevens beschikbaar zijn zonder dat ze ongebruikte buffers bevatten.

Nul byte-leesbewerkingen met PipeReader

Met bufferloze leesbewerkingen ondersteund op SslStream, is er een optie toegevoegd om nul-byte-leesbewerkingen uit te voeren op StreamPipeReader, het interne type dat een Stream naar een PipeReader aanpast. In Kestrel wordt een StreamPipeReader gebruikt om de onderliggende SslStream aan te passen aan een PipeReader. Daarom was het noodzakelijk om deze nul-byte leessemantiek op de PipeReader bloot te leggen.

Er kan nu een PipeReader worden gemaakt die nul-byte leesbewerkingen ondersteunt op elk onderliggend Stream dat semantiek voor nul-byte lezen ondersteunt (bijvoorbeeld SslStream, NetworkStream, enzovoort) met behulp van de volgende API:

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

Platen verwijderen uit de SlabMemoryPool

Om de fragmentatie van de heap te verminderen, heeft Kestrel een techniek toegepast waarbij er geheugenslabs van 128 kB als onderdeel van de geheugenpool zijn toegewezen. De schijven werden vervolgens verder onderverdeeld in 4 kB blokken die intern door Kestrel werden gebruikt. De blokken moesten groter zijn dan 85 kB om toewijzing af te dwingen op de grote object-heap, zodat de GC deze array niet verplaatst. Met de introductie van de nieuwe generatie GC, Pinned Object Heap (POH), heeft het echter geen zin meer om blokken toe te wijzen op slab. Kestrel wijst nu rechtstreeks blokken toe aan de POH, waardoor de complexiteit van het beheren van de geheugengroep wordt verminderd. Deze wijziging moet het gemakkelijker maken om toekomstige verbeteringen uit te voeren, zoals het gemakkelijker maken om de geheugengroep te verkleinen die wordt gebruikt door Kestrel.

Ondersteuning van IAsyncDisposable

IAsyncDisposable is nu beschikbaar voor controllers, Razor pagina's en weergaveonderdelen. Asynchrone versies zijn toegevoegd aan de relevante interfaces bij fabrieken en activators.

  • De nieuwe methoden bieden een standaardinterface-implementatie die delegeert naar de synchrone versie en vervolgens Dispose aanroept.
  • De implementaties overschrijven de standaardimplementatie en zorgen voor het afhandelen van het verwijderen van IAsyncDisposable implementaties.
  • De implementaties geven de voorkeur IAsyncDisposable aan IDisposable wanneer beide interfaces worden geïmplementeerd.
  • Extenders moeten de nieuwe methoden overschrijven die zijn opgenomen om IAsyncDisposable exemplaren te ondersteunen.

IAsyncDisposable is nuttig bij het werken met:

  • Asynchrone enumerators, bijvoorbeeld in asynchrone gegevensstromen.
  • Onbeheerde resources met resource-intensieve I/O-bewerkingen om vrij te geven.

Wanneer u deze interface implementeert, gebruikt u de DisposeAsync methode om resources vrij te geven.

Overweeg een controller die een Utf8JsonWriter maakt en gebruikt. Utf8JsonWriter is een IAsyncDisposable bron:

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 moet DisposeAsync implementeren.

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

    _jsonWriter = null;
}

Vcpkg-poort voor SignalR C++-client

Vcpkg is een platformoverschrijdend opdrachtregelpakketbeheer voor C- en C++-bibliotheken. We hebben onlangs een poort toegevoegd om systeemeigen ondersteuning toe te vcpkg voegen CMake voor de SignalR C++-client. vcpkg werkt ook met MSBuild.

De SignalR client kan worden toegevoegd aan een CMake-project met het volgende codefragment wanneer de vcpkg is opgenomen in het toolchainbestand:

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

Met het voorgaande codefragment is de SignalR C++-client klaar voor gebruik #include en gebruikt in een project zonder extra configuratie. Zie de SignalR voor een volledig voorbeeld van een C++-toepassing die gebruikmaakt van de SignalR C++-client.

Blazor

Projectsjabloonwijzigingen

Er zijn verschillende projectsjabloonwijzigingen aangebracht voor Blazor apps, waaronder het gebruik van het Pages/_Layout.cshtml bestand voor indelingsinhoud die in het _Host.cshtml bestand voor eerdere Blazor Server apps werd weergegeven. Bekijk de wijzigingen door een app te maken op basis van een 6.0-projectsjabloon of door toegang te krijgen tot de ASP.NET Core-referentiebron voor de projectsjablonen:

Blazor WebAssembly ondersteuning voor systeemeigen afhankelijkheden

Blazor WebAssembly-apps kunnen systeemeigen afhankelijkheden gebruiken die zijn gebouwd om te worden uitgevoerd op WebAssembly. Zie ASP.NET Systeemeigen kernafhankelijkheden Blazor WebAssemblyvoor meer informatie.

WebAssembly Ahead-of-time (AOT)-compilatie en runtime-herlinking

Blazor WebAssembly biedt ondersteuning voor AOT-compilatie (ahead-of-time), waar u uw .NET-code rechtstreeks in WebAssembly kunt compileren. AOT-compilatie resulteert in runtime-prestatieverbeteringen ten koste van een grotere app-grootte. Als u de .NET WebAssembly-runtime opnieuw koppelt, wordt ongebruikte runtimecode beperkt en wordt de downloadsnelheid dus verbeterd. Zie AOT-compilatie (Ahead-of-Time) en Runtime-relinking voor meer informatie.

Vooraf gerenderde toestand behouden

Blazor ondersteunt persistente status op een vooraf geplaatste pagina, zodat de status niet opnieuw hoeft te worden gemaakt wanneer de app volledig is geladen. Zie Integreer ASP.NET Core Razor-onderdelen met MVC of Razor Pagesvoor meer informatie.

Foutgrenzen

Foutgrenzen bieden een handige benadering voor het afhandelen van uitzonderingen op gebruikersinterfaceniveau. Zie Fouten afhandelen in ASP.NET Core Blazor-appsvoor meer informatie.

SVG-ondersteuning

Het <foreignObject> elementelement wordt ondersteund om willekeurige HTML in een SVG weer te geven. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Blazor Server ondersteuning voor bytematrixoverdracht in JS Interop

Blazor ondersteunt geoptimaliseerde byte-array-interop JS die het coderen en decoderen van byte-arrays naar Base64 voorkomt. Zie de volgende bronnen voor meer informatie:

Verbeteringen van queryreeksen

Ondersteuning voor het werken met queryreeksen is verbeterd. Zie ASP.NET Core-navigatie Blazorvoor meer informatie.

Binding om meerdere te selecteren

Binding ondersteunt selectie van meerdere opties met <input> elementen. Zie de volgende bronnen voor meer informatie:

Inhoudsbeheer hoofdsectie (<head>)

Razor onderdelen kunnen de HTML-elementinhoud <head> van een pagina wijzigen, waaronder het instellen van de titel (<title> element) van de pagina en het wijzigen van metagegevens (<meta> elementen). Zie Inhoud <head> beheren in ASP.NET Core-apps Blazorvoor meer informatie.

Angular- en React-onderdelen genereren

Frameworkspecifieke JavaScript-onderdelen genereren op basis van Razor onderdelen voor webframeworks, zoals Angular of React. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Onderdelen weergeven vanuit JavaScript

Onderdelen dynamisch weergeven Razor vanuit JavaScript voor bestaande JavaScript-apps. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Aangepaste elementen

Experimentele ondersteuning is beschikbaar voor het bouwen van aangepaste elementen, die gebruikmaken van standaard HTML-interfaces. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Generieke typen componenten afleiden van oudercomponenten

Een bovenliggend onderdeel kan een typeparameter op naam doorgeven aan afstammelingen met behulp van het nieuwe [CascadingTypeParameter] kenmerk. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Dynamisch gerenderde onderdelen

Gebruik het nieuwe ingebouwde DynamicComponent onderdeel om onderdelen per type weer te geven. Zie Dynamisch gerenderde ASP.NET Core-onderdelen Razorvoor meer informatie.

Verbeterde Blazor toegankelijkheid

Gebruik het nieuwe FocusOnNavigate onderdeel om de focus van de gebruikersinterface in te stellen op een element op basis van een CSS-selector nadat u van de ene pagina naar de andere navigeert. Zie ASP.NET Core-routering Blazorvoor meer informatie.

Ondersteuning voor aangepaste gebeurtenisargumenten

Blazor ondersteunt aangepaste gebeurtenisargumenten, waarmee u willekeurige gegevens kunt doorgeven aan .NET-gebeurtenis-handlers met aangepaste gebeurtenissen. Zie ASP.NET Core Blazor event handlingvoor meer informatie.

Vereiste parameters

Pas het nieuwe [EditorRequired] kenmerk toe om een vereiste onderdeelparameter op te geven. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

Samenvoeging van JavaScript-bestanden met pagina's, weergaven en componenten

Plaats JavaScript-bestanden voor pagina's, weergaven en Razor onderdelen als een handige manier om scripts in een app te organiseren. Zie ASP.NET Core Blazor JavaScript-interoperabiliteit (JS interop)voor meer informatie.

JavaScript-initialisaties

JavaScript-initializers voeren logica uit voor en nadat een Blazor app is geladen. Zie ASP.NET Core Blazor JavaScript-interoperabiliteit (JS interop)voor meer informatie.

JavaScript-interop streamen

Blazor ondersteunt nu het rechtstreeks streamen van gegevens tussen .NET en JavaScript. Zie de volgende bronnen voor meer informatie:

Algemene typebeperkingen

Algemene typeparameters worden nu ondersteund. Zie ASP.NET Core Razor-onderdelenvoor meer informatie.

WebAssembly-implementatie-indeling

Gebruik een implementatie-indeling om app-downloads in te schakelen Blazor WebAssembly in beperkte beveiligingsomgevingen. Zie De implementatie-indeling voor gehoste Blazor WebAssembly ASP.NET Core-apps voor meer informatie.

Nieuwe Blazor artikelen

Naast de Blazor functies die in de voorgaande secties worden beschreven, zijn er nieuwe Blazor artikelen beschikbaar over de volgende onderwerpen:

Apps bouwen Blazor Hybrid met .NET MAUI WPF en Windows Forms

Gebruik Blazor Hybrid om desktop- en mobiele systeemeigen clientframeworks te combineren met .NET en Blazor:

  • .NET Multi-platform App UI (.NET MAUI) is een platformoverschrijdend framework voor het maken van systeemeigen mobiele en desktop-apps met C# en XAML.
  • Blazor Hybrid apps kunnen worden gebouwd met WPF-frameworks (Windows Presentation Foundation) en Windows Forms.

Belangrijk

Blazor Hybrid is in preview en mag niet in productie-apps worden gebruikt totdat de definitieve release beschikbaar is.

Zie de volgende bronnen voor meer informatie:

Kestrel

HTTP/3 is momenteel in concept en kan daarom worden gewijzigd. HTTP/3-ondersteuning in ASP.NET Core wordt niet uitgebracht. Het is een preview-functie die is opgenomen in .NET 6.

Kestrel ondersteunt nu HTTP/3. Zie HTTP/3 gebruiken met de ASP.NET Core-webserver Kestrel en het blogbericht HTTP/3-ondersteuning in .NET 6 voor meer informatie.

Nieuwe Kestrel logcategorieën voor geselecteerde logboekregistratie

Vóór deze wijziging was het inschakelen van uitgebreide logboekregistratie voor Kestrel onbetaalbaar omdat de hele Kestrel de Microsoft.AspNetCore.Server.Kestrel logboekregistratiecategorienaam deelde. Microsoft.AspNetCore.Server.Kestrel is nog steeds beschikbaar, maar de volgende nieuwe subcategorieën bieden meer controle over logboekregistratie:

  • Microsoft.AspNetCore.Server.Kestrel(huidige categorie): ApplicationError, , ConnectionHeadResponseBodyWriteApplicationNeverCompleted, RequestBodyStart, , RequestBodyDone, RequestBodyNotEntirelyRead, RequestBodyDrainTimedOut, ResponseMinimumDataRateNotSatisfied, InvalidResponseHeaderRemovedHeartbeatSlow
  • 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, . Http2FrameSendingHttp2MaxConcurrentStreamsReached
  • Microsoft.AspNetCore.Server.Kestrel.Http3: Http3ConnectionError, Http3ConnectionClosing, Http3ConnectionClosed, , Http3StreamAbort, , Http3FrameReceived. Http3FrameSending

Bestaande regels blijven werken, maar u kunt nu selectiever zijn voor welke regels u inschakelt. De waarneembaarheidsoverhead voor het inschakelen Debug van logboekregistratie voor alleen ongeldige aanvragen is bijvoorbeeld aanzienlijk verminderd en kan worden ingeschakeld met de volgende configuratie:

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

Bij logboekfiltering worden regels toegepast met het langste overeenkomende categorievoorvoegsel. Zie Hoe filterregels worden toegepast voor meer informatie

KestrelServerOptions uitgeven via EventSource-gebeurtenis

De KestrelEventSource verzendt een nieuwe gebeurtenis met de JSON-serialisatie KestrelServerOptions wanneer deze is ingeschakeld met uitgebreidheidEventLevel.LogAlways. Met deze gebeurtenis kunt u gemakkelijker redeneren over het servergedrag bij het analyseren van verzamelde traceringen. De volgende JSON is een voorbeeld van de nettolading van de gebeurtenis:

{
  "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"
    }
  ]
}

Nieuwe diagnostische bron-gebeurtenis voor geweigerde HTTP-aanvragen

Kestrel verzendt nu een nieuwe DiagnosticSource gebeurtenis voor HTTP-aanvragen die zijn geweigerd op de serverlaag. Voorafgaand aan deze wijziging is er geen manier om deze geweigerde aanvragen te observeren. De nieuwe DiagnosticSource gebeurtenis bevat een Microsoft.AspNetCore.Server.Kestrel.BadRequest gebeurtenis IBadRequestExceptionFeature die kan worden gebruikt om de reden voor het afwijzen van de aanvraag introspect.

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

Zie Logboekregistratie en diagnostische gegevens in Kestrelvoor meer informatie.

Een ConnectionContext maken vanuit een Accept Socket

Het nieuwe SocketConnectionContextFactory maakt het mogelijk om een ConnectionContext van een geaccepteerde socket te maken. Dit maakt het mogelijk om een aangepaste socket-gebaseerde IConnectionListenerFactory te bouwen zonder dat alle prestatieverbeteringen en pooling in SocketConnection verloren gaan.

Zie dit voorbeeld van een aangepaste IConnectionListenerFactory die laat zien hoe u dit SocketConnectionContextFactorykunt gebruiken.

Kestrel is het standaardlanceringsprofiel voor Visual Studio

Het standaardlanceringsprofiel voor alle nieuwe dotnet-webprojecten is Kestrel. Het starten Kestrel is aanzienlijk sneller en resulteert in een responsievere ervaring tijdens het ontwikkelen van apps.

IIS Express is nog steeds beschikbaar als een startprofiel voor scenario's zoals Windows-verificatie of het delen van poorten.

Poorten voor Kestrel op localhost zijn willekeurig.

Zie door sjabloon gegenereerde poorten voor Kestrel in dit document voor meer informatie.

Verificatie en autorisatie

Verificatieservers

.NET 3 tot .NET 5 heeft IdentityServer4 gebruikt als onderdeel van onze sjabloon ter ondersteuning van de uitgifte van JWT-tokens voor SPA en Blazor toepassingen. De sjablonen gebruiken nu de Duende Identity Server.

Als u de identiteitsmodellen uitbreidt en bestaande projecten bijwerkt, werkt u de naamruimten in uw code bij van IdentityServer4.IdentityServer naar Duende.IdentityServer en volgt u de migratie-instructies.

Het licentiemodel voor Duende Identity Server is gewijzigd in een wederzijdse licentie, waarvoor mogelijk licentiekosten nodig zijn wanneer het commercieel in productie wordt gebruikt. Zie de duende-licentiepagina voor meer informatie.

Vertraagde onderhandeling van clientcertificaten

Ontwikkelaars kunnen zich nu aanmelden voor het gebruik van vertraagde onderhandeling van clientcertificaten door ClientCertificateMode.DelayCertificate op te geven op de HttpsConnectionAdapterOptions. Dit werkt alleen met HTTP/1.1-verbindingen omdat HTTP/2 vertraagde heronderhandeling van certificaten verbiedt. De aanroeper van deze API moet de aanvraagbody bufferen voordat het clientcertificaat wordt aangevraagd:

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

Cookie verschuifbare verlooptijd van verificatie kan nu worden aangepast of onderdrukt met behulp van het nieuwe OnCheckSlidingExpiration. Deze gebeurtenis kan bijvoorbeeld worden gebruikt door een app met één pagina die de server periodiek moet pingen zonder dat dit van invloed is op de verificatiesessie.

Allerlei

Onmiddellijk Herladen

Maak snel ui- en code-updates voor het uitvoeren van apps zonder dat de app-status verloren gaat voor snellere en productievere ontwikkelaarservaring met behulp van Hot Reload. Zie ondersteuning voor .NET Hot Reload voor ASP.NET Core en Update op de voortgang van .NET Hot Reload en Visual Studio 2022 voor meer informatie.

Verbeterde spa-sjablonen (app met één pagina)

De ASP.NET Core-projectsjablonen zijn bijgewerkt voor Angular en React om een verbeterd patroon te gebruiken voor apps met één pagina die flexibeler is en beter aansluit bij algemene patronen voor moderne front-endwebontwikkeling.

Voorheen gebruikte de ASP.NET Core-sjabloon voor Angular en React gespecialiseerde middleware tijdens de ontwikkeling om de ontwikkelserver voor het front-endframework te starten en vervolgens proxyaanvragen van ASP.NET Core naar de ontwikkelserver. De logica voor het starten van de front-endontwikkelingsserver was specifiek voor de opdrachtregelinterface voor het bijbehorende front-endframework. Het ondersteunen van extra front-endframeworks met behulp van dit patroon betekende dat u extra logica toevoegt aan ASP.NET Core.

De bijgewerkte ASP.NET Core-sjablonen voor Angular en React in .NET 6 spiegelt deze rangschikking om en profiteert van de ingebouwde proxyondersteuning op de ontwikkelservers van de meeste moderne front-endframeworks. Wanneer de ASP.NET Core-app wordt gestart, wordt de front-endontwikkelingsserver net als voorheen gestart, maar de ontwikkelserver is geconfigureerd voor proxyaanvragen naar de back-end ASP.NET Core-proces. Alle front-endspecifieke configuratie voor het instellen van proxy's maakt deel uit van de app, niet ASP.NET Core. Het instellen van ASP.NET Core-projecten voor gebruik met andere front-endframeworks is nu eenvoudig: stel de front-endontwikkelingsserver in voor het gekozen framework om naar de ASP.NET Core-back-end te proxyen met behulp van het patroon dat is vastgesteld in de Angular- en React-sjablonen.

De opstartcode voor de ASP.NET Core-app heeft geen app-specifieke logica met één pagina meer nodig. De logica voor het starten van de front-endontwikkelingsserver tijdens de ontwikkeling wordt tijdens runtime in de app ingevoerd door het nieuwe Microsoft.AspNetCore.SpaProxy-pakket . Fallback-routering wordt afgehandeld met eindpuntroutering in plaats van SPA-specifieke middleware.

Sjablonen die dit patroon volgen, kunnen nog steeds worden uitgevoerd als één project in Visual Studio of vanaf dotnet run de opdrachtregel. Wanneer de app wordt gepubliceerd, wordt de front-endcode in de map ClientApp gebouwd en verzameld zoals voorheen in de webhoofdmap van de host ASP.NET Core-app en diende als statische bestanden. Scripts die zijn opgenomen in de sjabloon configureren de front-endontwikkelingsserver voor het gebruik van HTTPS met behulp van het ASP.NET Core-ontwikkelingscertificaat.

Ontwerpversie HTTP/3-ondersteuning in .NET 6

HTTP/3 is momenteel in concept en kan daarom worden gewijzigd. HTTP/3-ondersteuning in ASP.NET Core wordt niet uitgebracht. Het is een preview-functie die is opgenomen in .NET 6.

Zie het blogbericht HTTP/3-ondersteuning in .NET 6.

Nulbare referentietypen aantekeningen

Op delen van de ASP.NET Core in .NET 6-broncode zijn nullabiliteitsannotaties toegepast.

Door gebruik te maken van de nieuwe Nullable-functie in C# 8, kan ASP.NET Core extra gecompileerde veiligheid bieden bij de verwerking van referentietypen. Bijvoorbeeld, bescherming bieden tegen null-verwijzingsfouten. Projecten die hebben gekozen voor het gebruik van nullable annotaties, kunnen nieuwe build-tijdwaarschuwingen van API's van ASP.NET Core zien.

Als u null-referentietypen wilt inschakelen, voegt u de volgende eigenschap toe aan projectbestanden:

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

Voor meer informatie, zie Nullbare referentietypen.

Broncodeanalyse

Er zijn verschillende .NET-compilerplatformanalyses toegevoegd die toepassingscode controleren op problemen zoals onjuiste middlewareconfiguratie of -volgorde, routeringsconflicten, enzovoort. Zie Codeanalyse in ASP.NET Core-apps voor meer informatie.

Verbeteringen aan web-app-sjablonen

De web-app-sjablonen:

Door sjabloon gegenereerde poorten voor Kestrel

Willekeurige poorten worden toegewezen tijdens het maken van het project voor gebruik door de Kestrel webserver. Willekeurige poorten helpen bij het minimaliseren van een poortconflict wanneer meerdere projecten op dezelfde computer worden uitgevoerd.

Wanneer een project wordt gemaakt, wordt een willekeurige HTTP-poort tussen 5000-5300 en een willekeurige HTTPS-poort tussen 7000-7300 opgegeven in het gegenereerde Properties/launchSettings.json bestand. De poorten kunnen in het Properties/launchSettings.json bestand worden gewijzigd. Als er geen poort is opgegeven, Kestrel worden standaard de HTTP 5000- en HTTPS 5001-poorten gebruikt. Zie Eindpunten configureren voor de ASP.NET Core Kestrel webservervoor meer informatie.

Nieuwe standaardinstellingen voor logboekregistratie

De volgende wijzigingen zijn aangebracht in beide appsettings.json en appsettings.Development.json:

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

De wijziging van "Microsoft": "Warning" in "Microsoft.AspNetCore": "Warning" leidt tot het vastleggen van alle informatieve berichten uit de Microsoft naamruimte behalveMicrosoft.AspNetCore. Bijvoorbeeld, Microsoft.EntityFrameworkCore wordt nu geregistreerd op een informatieniveau.

Automatisch toegevoegde middleware voor ontwikkelaarsuitzonderingspagina

In de ontwikkelomgeving wordt de DeveloperExceptionPageMiddleware standaard toegevoegd. Het is niet meer nodig om de volgende code toe te voegen aan web-UI-apps:

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

Ondersteuning voor Latin1 gecodeerde aanvraagheaders in HttpSysServer

HttpSysServer biedt nu ondersteuning voor het decoderen van aanvraagheaders die zijn Latin1 gecodeerd door de eigenschap UseLatin1RequestHeaders op HttpSysOptions in te stellen op true:

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

var app = builder.Build();

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

app.Run();

De ASP.NET Core Module-logboeken bevatten tijdstempels en PID

De ASP.NET Core Module (ANCM) voor uitgebreide diagnostische logboeken van IIS (ANCM) bevatten tijdstempels en PID van het proces dat de logboeken verzendt. Met tijdstempels en PID voor logboekregistratie kunt u gemakkelijker problemen vaststellen met overlappende processtarts in IIS wanneer meerdere IIS-werkprocessen worden uitgevoerd.

De resulterende logboeken lijken nu op de voorbeelduitvoer die hieronder wordt weergegeven:

[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: ''

Configureerbare niet-geconsumeerde binnenkomende buffergrootte voor IIS

De IIS-server bufferde voorheen slechts 64 KiB aan niet-verbruikte aanvraaglichamen. De 64 KiB-buffering heeft geresulteerd in leesbewerkingen die beperkt zijn tot die maximale grootte, wat van invloed is op de prestaties met grote inkomende gegevensbestanden, zoals uploads. In .NET 6 verandert de standaardbuffergrootte van 64 KiB in 1 MiB, wat de doorvoer voor grote uploads moet verbeteren. In onze tests duurt een upload van 700 MiB die 9 seconden duurde, nu slechts 2,5 seconden.

Het nadeel van een grotere buffergrootte is een verhoogd geheugenverbruik per aanvraag wanneer de app niet snel leest vanuit de aanvraagbody. Naast het wijzigen van de standaardbuffergrootte kan de buffergrootte dus worden geconfigureerd, zodat apps de buffergrootte kunnen configureren op basis van de workload.

Helpers voor onderdelentags weergeven

Overweeg een weergaveonderdeel met een optionele parameter, zoals wordt weergegeven in de volgende code:

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

Met ASP.NET Core in .NET 6 kan de taghelper worden aangeroepen zonder dat u een waarde hoeft op te geven voor de showSomething parameter:

<vc:my />

Angular-sjabloon bijgewerkt naar Angular 12

De ASP.NET Core in .NET 6-sjabloon voor Angular gebruikt nu Angular 12.

De React-sjabloon is bijgewerkt naar React 17.

Configureerbare bufferdrempel voordat u naar schijf schrijft in Json.NET uitvoerindeling

Opmerking: Het is raadzaam om de System.Text.Json uitvoerindeling te gebruiken, behalve wanneer de Newtonsoft.Json serializer is vereist om compatibiliteitsredenen. De System.Text.Json serializer is volledig async en werkt efficiënt voor grotere payloads.

De Newtonsoft.Json uitvoerformatter buffert standaard reacties van maximaal 32 KiB in het geheugen voordat er naar schijf wordt gebufferd. Dit is om te voorkomen dat synchrone IO wordt uitgevoerd, met als gevolg andere neveneffecten, zoals thread-uitputting en applicatie-deadlocks. Als het antwoord echter groter is dan 32 KiB, treedt er aanzienlijke schijf-I/O op. De geheugendrempel kan nu worden geconfigureerd via de eigenschap MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold voordat u buffert op schijf:

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

Zie deze GitHub-pull-aanvraag en het NewtonsoftJsonOutputFormatterTest.cs-bestand voor meer informatie.

Sneller ophalen en instellen voor HTTP-headers

Er zijn nieuwe API's toegevoegd om alle algemene headers die beschikbaar zijn op Microsoft.Net.Http.Headers.HeaderNames als eigenschappen van IHeaderDictionary weer te geven, waardoor de API eenvoudiger te gebruiken is. De inline middleware in de volgende code haalt bijvoorbeeld aanvraag- en antwoordheaders op en stelt deze in met behulp van de nieuwe API's:

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

Voor geïmplementeerde kopteksten worden de get- en set-accessors geïmplementeerd door direct naar het veld te gaan en de zoekactie te omzeilen. Voor niet-geïmplementeerde headers kunnen de accessors de eerste zoekactie omzeilen op basis van geïmplementeerde headers en de Dictionary<string, StringValues> zoekopdracht rechtstreeks uitvoeren. Het voorkomen van de zoekactie resulteert in snellere toegang voor beide scenario's.

Asynchroon streamen

ASP.NET Core ondersteunt nu asynchrone streaming vanuit controlleracties en -antwoorden van de JSON-formatter. Het retourneren van een IAsyncEnumerable vanuit een actie zorgt ervoor dat de antwoordinhoud niet langer in het geheugen wordt gebufferd voordat deze wordt verzonden. Niet bufferen helpt het geheugengebruik te verminderen bij het retourneren van grote gegevenssets die asynchroon kunnen worden geïnventariseerd.

Entity Framework Core biedt implementaties voor het uitvoeren van IAsyncEnumerable query's op de database. De verbeterde ondersteuning voor IAsyncEnumerable in ASP.NET Core in .NET 6 kan het gebruik met EF Core ASP.NET Core efficiënter maken. Met de volgende code worden de productgegevens bijvoorbeeld niet meer in het geheugen gebufferd voordat het antwoord wordt verzonden:

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

Wanneer u echter luie laadbewerkingen gebruikt in EF Core, kan dit nieuwe gedrag leiden tot fouten als gevolg van gelijktijdige uitvoering van query's terwijl de gegevens worden opgesomd. Apps kunnen terugkeren naar het vorige gedrag door de gegevens te bufferen:

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

Zie de gerelateerde aankondiging voor meer informatie over deze wijziging in gedrag.

Middleware voor HTTP-logboekregistratie

HTTP-logboekregistratie is een nieuwe ingebouwde middleware die informatie over HTTP-aanvragen en HTTP-antwoorden registreert, waaronder de headers en de volledige hoofdtekst:

var builder = WebApplication.CreateBuilder(args);

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

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

app.Run();

Navigeren naar / met de vorige code registreert informatie vergelijkbaar met de volgende uitvoer:

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

De voorgaande uitvoer is ingeschakeld met het volgende appsettings.Development.json bestand:

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

HTTP-logboekregistratie biedt logboeken van:

  • HTTP-aanvraaggegevens
  • Gemeenschappelijke eigenschappen
  • Kopteksten
  • Lichaam
  • HTTP-antwoordinformatie

Als u de middleware voor HTTP-logboekregistratie wilt configureren, geeft u het volgende op HttpLoggingOptions:

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

De IConnectionSocketFeature aanvraagfunctie biedt toegang tot de onderliggende acceptsocket die is gekoppeld aan de huidige aanvraag. Het is toegankelijk via de FeatureCollection op HttpContext.

Met de volgende app wordt bijvoorbeeld de LingerState eigenschap ingesteld op de geaccepteerde socket:

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

Algemene typebeperkingen in Razor

Bij het definiëren van algemene typeparameters in Razor het gebruik van de @typeparam instructie kunnen algemene typebeperkingen nu worden opgegeven met behulp van de standaard C#-syntaxis:

Kleinere SignalRscripts, Blazor Serveren MessagePack

MessagePack SignalRen Blazor Server scripts zijn nu aanzienlijk kleiner, waardoor kleinere downloads mogelijk zijn, minder JavaScript-parsering en compilatie door de browser en sneller opstarten. De grootteverminderingen:

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

De kleinere scripts zijn het resultaat van een bijdrage van de gemeenschap van Ben Adams. Zie de GitHub-pull-aanvraag van Ben voor meer informatie over de details van de groottevermindering.

Redis-profileringssessies inschakelen

Een communitybijdrage van Gabriel Lucaci maakt profileringssessie met Microsoft.Extensions.Caching.StackExchangeRedis mogelijk:

using StackExchange.Redis.Profiling;

var builder = WebApplication.CreateBuilder(args);

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

Zie StackExchange.Redis Profilering voor meer informatie.

Schaduwkopie in IIS

Er is een experimentele functie toegevoegd aan de ASP.NET Core Module (ANCM) voor IIS om ondersteuning toe te voegen voor schaduwkopieertoepassingsassembly's. Op dit moment vergrendelt .NET binaire bestanden van toepassingen wanneer deze worden uitgevoerd in Windows, waardoor het onmogelijk is om binaire bestanden te vervangen wanneer de app wordt uitgevoerd. Hoewel onze aanbeveling overblijft om een offline-app-bestand te gebruiken, herkennen we dat er bepaalde scenario's (bijvoorbeeld FTP-implementaties) zijn waarin dit niet mogelijk is.

Schakel in dergelijke scenario's schaduwkopie in door de handlerinstellingen van de ASP.NET Core-module aan te passen. In de meeste gevallen hebben ASP.NET Core-apps geen web.config in broncodebeheer staan die u kunt wijzigen. In ASP.NET Core web.config wordt gewoonlijk gegenereerd door de SDK. Het volgende voorbeeld web.config kan worden gebruikt om aan de slag te gaan:

<?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>

Schaduwkopie in IIS is een experimentele functie die niet gegarandeerd deel uitmaakt van ASP.NET Core. Geef feedback over IIS Shadow copying in dit GitHub-probleem.

Brekende wijzigingen

Gebruik de artikelen in Belangrijke wijzigingen in .NET om belangrijke wijzigingen te vinden die van toepassing kunnen zijn bij het upgraden van een app naar een nieuwere versie van .NET.

Aanvullende bronnen