Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln belyser de viktigaste ändringarna i ASP.NET Core i .NET 6 med länkar till relevant dokumentation.
ASP.NET Core MVC och Razor förbättringar
Minimala API:er
Minimala API:er har skapats för att skapa HTTP-API:er med minimala beroenden. De är idealiska för mikrotjänster och appar som bara vill inkludera de minsta filerna, funktionerna och beroendena i ASP.NET Core. Mer information finns i:
- Självstudie: Skapa ett minimalt API med ASP.NET Core
- Skillnader mellan minimala API:er och API:er med kontrollanter
- Snabbreferens för minimala API:er
- Kodexempel som migrerats till den nya minimala värdmodellen i 6.0
SignalR
Aktivitetstagg för långvariga SignalR anslutningar
SignalR använder den nya Microsoft.AspNetCore.Http.Features.IHttpActivityFeature.Activity för att lägga till en http.long_running tagg i begärandeaktiviteten.
IHttpActivityFeature.Activity används av APM-tjänster som Azure Monitor Application Insights för att filtrera SignalR begäranden från att skapa långvariga begärandeaviseringar.
SignalR Prestandaförbättringar
- Allokera HubCallerClients en gång per anslutning i stället för varje hubbmetodanrop.
- Undvik stängningsallokering i SignalR
DefaultHubDispatcher.Invoke. Tillståndet överförs till en lokal statisk funktion via parametrar för att undvika en slutande funktionsallokering. Mer information finns i denna pull request på GitHub. - Allokera en enskild StreamItemMessage per ström i stället för per strömelement i server-till-klient-strömning. Mer information finns i denna pull request på GitHub.
Razor kompilator
Razor kompilatorn har uppdaterats för att använda källgeneratorer
Kompilatorn Razor baseras nu på C#-källgeneratorer. Källgeneratorer körs under kompilering och inspekterar vad som kompileras för att skapa ytterligare filer som kompileras tillsammans med resten av projektet. Att använda källgeneratorer förenklar Razor kompilatorn och påskyndar byggtiderna avsevärt.
Razor kompilatorn skapar inte längre en separat views-sammansättning
Kompilatorn Razor använde tidigare en kompileringsprocess i två steg som skapade en separat views-sammansättning som innehöll de genererade vyer och sidor (.cshtml filer) som definierats i appen. De genererade typerna var offentliga och under AspNetCore namnområdet.
Den uppdaterade Razor kompilatorn skapar vyerna och sidtyperna i huvudprojektsammansättningen. Dessa typer genereras nu som standard som intern förseglade i AspNetCoreGeneratedDocument namnområdet. Den här ändringen förbättrar byggprestandan, aktiverar distribution av enskilda filer och gör att dessa typer kan delta i frekvent omläsning.
Mer information om den här ändringen finns i den relaterade tillkännagivandefrågan på GitHub.
ASP.NET Core-prestanda och API-förbättringar
Många ändringar har gjorts för att minska allokeringarna och förbättra prestandan i stacken:
- Icke-allokerande app.Use utökningsmetod. Den nya överlagringen av
app.Usekräver att du skickar kontexten tillnextvilken sparar två interna allokeringar per begäran som krävs när du använder den andra överbelastningen. - Minskade minnesallokeringar vid åtkomst till HttpRequest.Cookies. Mer information finns i det här GitHub-problemet.
- Använd LoggerMessage.Define för windows endastHTTP.sys webbserver. Anropen till ILogger-tilläggsmetoderna har ersatts med anrop till
LoggerMessage.Define. - Minska belastningen per anslutning i SocketConnection med ~30%. Mer information finns i denna pull request på GitHub.
- Minska allokeringarna genom att ta bort loggningsdelegater i generiska typer. Mer information finns i denna pull request på GitHub.
- Snabbare GET-åtkomst (cirka 50%) till vanliga funktioner som IHttpRequestFeature, IHttpResponseFeature, IHttpResponseBodyFeature, IRouteValuesFeatureoch IEndpointFeature. Mer information finns i denna pull request på GitHub.
- Använd enstaka instanssträngar för kända rubriknamn, även om de inte finns i det bevarade rubrikblocket. Genom att använda en instanssträng kan du förhindra flera dubbletter av samma sträng i långvariga anslutningar, till exempel i Microsoft.AspNetCore.WebSockets. Mer information finns i det här GitHub-problemet.
- Återanvänd HttpProtocol CancellationTokenSource i Kestrel. Använd den nya metoden CancellationTokenSource.TryReset på
CancellationTokenSourceför att återanvända tokens om de inte har avbrutits. Mer information finns i det här GitHub-problemet och den här videon. - Implementera och använda en AdaptiveCapacityDictionary i Microsoft.AspNetCore.HttpRequestCookieCollection för effektivare åtkomst till ordlistor. Mer information finns i denna pull request på GitHub.
Minskat minnesavtryck för inaktiva TLS-anslutningar
För tidskrävande TLS-anslutningar där data endast skickas ibland fram och tillbaka har vi avsevärt minskat minnesfotavtrycket för ASP.NET Core-appar i .NET 6. Detta bör bidra till att förbättra skalbarheten för scenarier som WebSocket-servrar. Detta var möjligt på grund av många förbättringar i System.IO.Pipelines, SslStreamoch Kestrel. I följande avsnitt beskrivs några av de förbättringar som har bidragit till det minskade minnesavtrycket:
Minska storleken på System.IO.Pipelines.Pipe
För varje anslutning som upprättas allokeras två rör i Kestrel:
- Transportlagret till appen för begäran.
- Programlagret till transporten för svaret.
Genom att minska storleken på System.IO.Pipelines.Pipe från 368 byte till 264 byte (cirka 28,2% minskning) sparas 208 byte per anslutning (104 byte per rör).
Pool SocketSender
SocketSender objekt (den underklassen SocketAsyncEventArgs) är cirka 350 byte vid körning. I stället för att allokera ett nytt SocketSender objekt per anslutning kan de poolas.
SocketSender objekt kan poolas eftersom sändningar vanligtvis är mycket snabba. Poolning minskar kostnaden per anslutning. I stället för att allokera 350 byte per anslutning allokeras endast 350 byte per IOQueue . Allokeringen görs per kö för att undvika konkurrens. Vår WebSocket-server med 5 000 inaktiva anslutningar gick från att allokera ~1,75 MB (350 byte * 5 000) till att allokera ~2,8 kb (350 byte * 8) för SocketSender objekt.
Noll-byte-läsningar med SslStream
Buffertlösa läsningar är en teknik som används i ASP.NET Core för att undvika att hyra minne från minnespoolen om det inte finns några tillgängliga data på socketen. Före den här ändringen krävde vår WebSocket-server med 5 000 inaktiva anslutningar ~200 MB utan TLS jämfört med ~800 MB med TLS. Vissa av dessa allokeringar (4 000 per anslutning) var från Kestrel att behöva hålla fast vid en ArrayPool<T> buffert i väntan på SslStream att läsningarna skulle slutföras. Med tanke på att dessa anslutningar var inaktiva slutförde ingen av läsningarna och returnerade sina buffertar till ArrayPool, vilket tvingade ArrayPool att allokera mer minne. De återstående allokeringarna var i själva SslStream: en 4k-buffert för TLS-handskakningar och en 32k-buffert för normala läsningar. När användaren i .NET 6 utför en noll byte-läsning på SslStream och det inte finns data tillgängliga, utför SslStream internt en nollbyteläsning på den underliggande omslutna strömmen. I bästa fall (inaktiv anslutning) resulterar dessa ändringar i en besparing på 40 kB per anslutning samtidigt som konsumenten (Kestrel) kan meddelas när data är tillgängliga utan att hålla fast vid oanvända buffertar.
Nollbyteläsningar med PipeReader
Med buffertlösa läsningar som stöds på SslStreamhar ett alternativ lagts till för att utföra noll byteläsningar till StreamPipeReader, den interna typen som anpassar en Stream till en PipeReader. I Kestrel används enStreamPipeReader för att anpassa SslStream till en PipeReader. Därför var det nödvändigt att exponera denna nollbytesläsningssemantik för PipeReader.
A PipeReader kan nu skapas som stöder läsningar av noll byte över alla underliggande Stream som stöder läsningssemantik för noll byte (t.ex. SslStream, NetworkStream osv.) med hjälp av följande API:
var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));
Ta bort plattor från SlabMemoryPool
För att minska fragmenteringen av heapminnet använde Kestrel en teknik där den allokerade minnesblock på 128 kB som en del av minnespoolen. Plattorna delades sedan ytterligare in i 4 KB-block som användes av Kestrel internt. Plattan måste vara större än 85 KB för att tvinga fram en allokering på den stora objekt-heapen och försöka förhindra att GC flyttar denna array. Men med introduktionen av den nya GC-generationen, Pinned Object Heap (POH), är det inte längre meningsfullt att allokera block på plattan. Kestrel allokerar nu block direkt på POH, vilket minskar komplexiteten i hanteringen av minnespoolen. Den här ändringen bör göra det enklare att utföra framtida förbättringar, till exempel att göra det lättare att krympa minnespoolen som används av Kestrel.
IAsyncDisposable stöds
IAsyncDisposable är nu tillgängligt för kontroller, Razor Sidor och vykomponenter. Asynkrona versioner har lagts till i relevanta gränssnitt i fabriker och aktivatorer:
- De nya metoderna erbjuder en standardgränssnittsimplementering som delegerar till den synkrona versionen och anropar Dispose.
- Genomförandena åsidosätter standardgenomförandet och hanterar avyttringen av
IAsyncDisposablegenomförandena. - Implementeringarna favoriserar
IAsyncDisposableöverIDisposablenär båda gränssnitten implementeras. - Utökare måste åsidosätta de nya metoder som ingår för att stödja
IAsyncDisposableinstanser.
IAsyncDisposable är fördelaktigt när du arbetar med:
- Asynkrona uppräknare, till exempel i asynkrona strömmar.
- Ohanterade resurser som har resursintensiva I/O-operationer att frigöra.
När du implementerar det här gränssnittet använder du DisposeAsync metoden för att frigöra resurser.
Överväg en kontrollant som skapar och använder en Utf8JsonWriter.
Utf8JsonWriter är en IAsyncDisposable resurs:
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 måste implementera DisposeAsync:
public async ValueTask DisposeAsync()
{
if (_jsonWriter is not null)
{
await _jsonWriter.DisposeAsync();
}
_jsonWriter = null;
}
Vcpkg-port för SignalR C++-klient
Vcpkg är en plattformsoberoende kommandoradspakethanterare för C- och C++-bibliotek. Vi har nyligen lagt till en port till vcpkg för att ge CMake inbyggt stöd åt SignalR C++-klienten.
vcpkg fungerar också med MSBuild.
Klienten SignalR kan läggas till i ett CMake-projekt med följande kodfragment när vcpkg ingår i verktygskedjans fil:
find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)
Med föregående kodfragment SignalR är C++-klienten redo att använda #include och användas i ett projekt utan någon ytterligare konfiguration. Ett fullständigt exempel på ett C++-program som använder SignalR C++-klienten finns i lagringsplatsen halter73/SignalR-Client-Cpp-Sample .
Blazor
Ändringar i projektmall
Flera ändringar i projektmallen har gjorts för Blazor appar, inklusive användning av Pages/_Layout.cshtml filen för layoutinnehåll som visades i _Host.cshtml filen för tidigare Blazor Server appar. Studera ändringarna genom att skapa en app från en 6.0-projektmall eller komma åt ASP.NET Core-referenskällan för projektmallarna:
Blazor WebAssembly stöd för inbyggda beroenden
Blazor WebAssembly appar kan använda inbyggda beroenden som skapats för att köras på WebAssembly. Mer information finns i ASP.NET ursprungliga Blazor WebAssembly kärnberoenden.
WebAssembly förkompilering (AOT) och omlänkning av exekvering
Blazor WebAssembly stöder AOT-kompilering (i förväg) där du kan kompilera .NET-koden direkt till WebAssembly. AOT-kompilering resulterar i förbättrad prestanda vid körning men leder till att appens storlek ökar. Genom att länka om .NET WebAssembly-runtime trimmas den oanvända runtime-koden, vilket förbättrar nedladdningshastigheten. Mer information finns i AOT-kompilering (ahead-of-time) och Runtime relinking.
Bevara fördefinierat tillstånd
Blazor stöder bestående tillstånd på en fördefinierad sida så att tillståndet inte behöver återskapas när appen är helt inläst. Mer information finns i Integrera ASP.NET Core Razor-komponenter med MVC eller Razor Pages.
Felgränser
Felgränser är en praktisk metod för att hantera undantag på användargränssnittsnivå. Mer information finns i Hantera fel i ASP.NET Core-apparBlazor.
SVG-stöd
Elementen <foreignObject> stöds för att visa valfri HTML i en SVG. Mer information finns i ASP.NET Core-komponenterRazor.
Blazor Server stöd för bytematrisöverföring i JS Interop
Blazor stöder optimerad bytematris JS interop som undviker kodning och avkodning av bytematriser till Base64. Mer information finns i följande resurser:
- Anropa JavaScript-funktioner från .NET-metoder i ASP.NET Core Blazor
- Anropa .NET-metoder från JavaScript-funktioner i ASP.NET Core Blazor
Förbättringar av söksträngar
Stöd för arbete med söksträngar har förbättrats. Mer information finns i ASP.NET Core-routning Blazor och navigering.
Bindning för att välja flera
Bindning stöder flera alternativval med <input> element. Mer information finns i följande resurser:
Innehållskontroll för head (<head>)
Razor komponenter kan ändra HTML-elementinnehållet <head> på en sida, inklusive att ange sidans rubrik (<title> element) och ändra metadata (<meta> element). Mer information finns i Kontrollera <head> innehåll i ASP.NET Core-apparBlazor.
Generera Angular- och React-komponenter
Generera ramverksspecifika JavaScript-komponenter från Razor komponenter för webbramverk, till exempel Angular eller React. Mer information finns i ASP.NET Core-komponenterRazor.
Rendera komponenter från JavaScript
Rendera Razor komponenter dynamiskt från JavaScript för befintliga JavaScript-appar. Mer information finns i ASP.NET Core-komponenterRazor.
Specialanpassade element
Experimentellt stöd är tillgängligt för att skapa anpassade element, som använder HTML-standardgränssnitt. Mer information finns i ASP.NET Core-komponenterRazor.
Härleda generiska typer av komponenter från överordnade komponenter
En förfaderkomponent kan kaskadera en namngiven typparameter till ättlingar med hjälp av det nya [CascadingTypeParameter]-attributet. Mer information finns i ASP.NET Core-komponenterRazor.
Dynamiskt renderade komponenter
Använd den nya inbyggda DynamicComponent komponenten för att återge komponenter efter typ. Mer information finns i Dynamiskt renderade ASP.NET Core-komponenterRazor.
Förbättrad Blazor tillgänglighet
Använd den nya FocusOnNavigate komponenten för att ange fokus för användargränssnittet till ett element baserat på en CSS-väljare när du har navigerat från en sida till en annan. Mer information finns i ASP.NET Core-routning Blazor och navigering.
Stöd för anpassade händelseargument
Blazor stöder anpassade händelseargument som gör att du kan skicka godtyckliga data till .NET-händelsehanterare med anpassade händelser. Mer information finns i ASP.NET Core Blazor händelsehantering.
Obligatoriska parametrar
Använd det nya [EditorRequired] attributet för att ange en obligatorisk komponentparameter. Mer information finns i ASP.NET Core-komponenterRazor.
Samplacering av JavaScript-filer med sidor, vyer och komponenter
Samordna JavaScript-filer för sidor, vyer och Razor komponenter som ett praktiskt sätt att organisera skript i en app. Mer information finns i ASP.NET Core Blazor JavaScript-samverkan (JS interop).
JavaScript-initierare
JavaScript-initierare kör logik före och efter att en Blazor app har lästs in. Mer information finns i ASP.NET Core Blazor JavaScript-samverkan (JS interop).
Direktuppspelning av JavaScript-interop
Blazor stöder nu direktuppspelning av data mellan .NET och JavaScript. Mer information finns i följande resurser:
Allmänna typbegränsningar
Nu stöds allmänna typparametrar. Mer information finns i ASP.NET Core-komponenterRazor.
Layout för WebAssembly-distribution
Använd en distributionslayout för att aktivera Blazor WebAssembly appnedladdningar i begränsade säkerhetsmiljöer. Mer information finns i Distribueringslayout för appar som är värdbaserade i ASP.NET CoreBlazor WebAssembly.
Nya Blazor artiklar
Utöver de Blazor funktioner som beskrivs i föregående avsnitt är nya Blazor artiklar tillgängliga i följande ämnen:
-
ASP.NET Core-filnedladdningarBlazor: Lär dig hur du laddar ned en fil med inbyggt
byte[]interop för direktuppspelning för att säkerställa effektiv överföring till klienten. - Visa bilder och dokument i ASP.NET Core Blazor: Upptäck hur du arbetar med bilder och dokument i Blazor appar, inklusive hur du strömmar bild- och dokumentdata.
Skapa Blazor Hybrid appar med .NET MAUI, WPF och Windows Forms
Använd Blazor Hybrid för att blanda skrivbords- och mobilbaserade klientramverk med .NET och Blazor:
- .NET Multi-platform App UI (.NET MAUI) är ett plattformsoberoende ramverk för att skapa interna mobil- och skrivbordsappar med C# och XAML.
- Blazor Hybrid appar kan skapas med Ramverk för Windows Presentation Foundation (WPF) och Windows Forms.
Viktigt!
Blazor Hybrid är i förhandsversion och bör inte användas i produktionsappar förrän den slutliga versionen har släppts.
Mer information finns i följande resurser:
- Förhandsversion av ASP.NET Core-dokumentation Blazor Hybrid
- Vad är .NET MAUI?
- Microsoft .NET-blogg (kategori: ".NET MAUI")
Kestrel
HTTP/3 är för närvarande i utkast och kan därför komma att ändras. HTTP/3-stöd i ASP.NET Core släpps inte, det är en förhandsversionsfunktion som ingår i .NET 6.
Kestrel stöder nu HTTP/3. Mer information finns i Använda HTTP/3 med ASP.NET Core-webbservern Kestrel och blogginlägget HTTP/3-stöd i .NET 6.
Nya Kestrel loggningskategorier för vald loggning
Innan förändringen var det för dyrt att aktivera utförlig loggning eftersom alla Kestrel delade Kestrel som namn på loggningskategorin.
Microsoft.AspNetCore.Server.Kestrel är fortfarande tillgängligt, men följande nya underkategorier ger mer kontroll över loggning:
-
Microsoft.AspNetCore.Server.Kestrel(aktuell kategori):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.
Befintliga regler fortsätter att fungera, men du kan nu vara mer selektiv när det gäller vilka regler du aktiverar. Till exempel minskar observerbarhetskostnaderna för att aktivera Debug loggning för bara felaktiga begäranden avsevärt och kan aktiveras med följande konfiguration:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.Kestrel.BadRequests": "Debug"
}
}
Loggfiltrering tillämpar regler med det längsta matchande kategoriprefixet. Mer information finns i Så här tillämpas filtreringsregler
Skicka ut KestrelServerOptions via EventSource-händelsen
KestrelEventSource genererar en ny händelse som innehåller JSON-serialiserad KestrelServerOptions när den aktiveras med verbositet EventLevel.LogAlways. Den här händelsen gör det enklare att resonera om serverbeteendet när du analyserar insamlade spårningar. Följande JSON är ett exempel på händelsens payload:
{
"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"
}
]
}
Ny DiagnosticSource-händelse för avvisade HTTP-begäranden
Kestrel genererar nu en ny DiagnosticSource händelse för HTTP-begäranden som avvisas på serverlagret. Före den här ändringen fanns det inget sätt att observera dessa avvisade begäranden. Den nya DiagnosticSource händelsen Microsoft.AspNetCore.Server.Kestrel.BadRequest innehåller en IBadRequestExceptionFeature som kan användas för att introspektera orsaken till att avvisa begäran.
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();
}
Mer information finns i Loggning och diagnostik i Kestrel.
Skapa en ConnectionContext från en Accept Socket
Den nya SocketConnectionContextFactory gör det möjligt att skapa en ConnectionContext från en godkänd socket. Detta gör det möjligt att skapa en anpassad socketbaserad IConnectionListenerFactory utan att förlora allt prestandaarbete och all pool som sker i SocketConnection.
Se det här exemplet på en anpassad IConnectionListenerFactory som visar hur du använder den här SocketConnectionContextFactory.
Kestrel är standardstartprofilen för Visual Studio
Standardstartprofilen för alla nya dotnet-webbprojekt är Kestrel. Start Kestrel är betydligt snabbare och resulterar i en mer dynamisk upplevelse när du utvecklar appar.
IIS Express är fortfarande tillgängligt som en startprofil för scenarier som Windows-autentisering eller portdelning.
Localhost-portar för Kestrel är slumpmässiga
Mer information finns i Mallgenererade portar för Kestrel i det här dokumentet.
Autentisering och auktorisering
Autentiseringsservrar
.NET 3 till .NET 5 använde IdentityServer4 som en del av vår mall för att stödja utfärdande av JWT-token för SPA och Blazor program. Mallarna använder nu Duende-servernIdentity.
Om du utökar identitetsmodellerna och uppdaterar befintliga projekt uppdaterar du namnrymderna i koden från IdentityServer4.IdentityServer till Duende.IdentityServer och följer deras migreringsinstruktioner.
Licensmodellen för Duende Identity Server har ändrats till en ömsesidig licens som kan kräva licensavgifter när den används kommersiellt i produktion. Mer information finns på sidan Duende-licens .
Fördröjd förhandling om klientcertifikat
Utvecklare kan nu välja att använda fördröjd klientcertifikatförhandling genom att ange ClientCertificateMode.DelayCertificate på HttpsConnectionAdapterOptions. Detta fungerar bara med HTTP/1.1-anslutningar eftersom HTTP/2 förbjuder fördröjd omförhandling av certifikat. Anroparen av det här API:et måste buffra begärandetexten innan klientcertifikatet begärs.
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();
OnCheckSlidingExpiration händelse för att hantera cookie förnyelse
Cookie förfallodatum för autentisering kan nu anpassas eller ignoreras med hjälp av den nya OnCheckSlidingExpiration. Den här händelsen kan till exempel användas av en single-page applikation som regelbundet behöver kontakta servern utan att påverka autentiseringssessionen.
Övrigt
Snabb omladdning
Gör snabbt användargränssnitts- och koduppdateringar till appar som körs utan att förlora tillståndet för appen, för en snabbare och mer produktiv utvecklarupplevelse med Hot Reload. Mer information finns i .NET Hot Reload-support för ASP.NET Core och Uppdatering om framsteg inom .NET Hot Reload och höjdpunkter i Visual Studio 2022.
Förbättrade mallar för enkeltsidig applikation (SPA)
De ASP.NET Core-projektmallarna har uppdaterats för Angular och React för att använda ett förbättrat mönster för enkelsidiga applikationer som är mer flexibelt och som bättre stämmer överens med vanliga mönster för modern webbutveckling för klientsidan.
Tidigare använde ASP.NET Core-mallen för Angular och React specialiserade mellanprogram under utvecklingen för att starta utvecklingsservern för klientdelsramverket och sedan proxybegäranden från ASP.NET Core till utvecklingsservern. Logiken för att starta klientdelsutvecklingsservern var specifik för kommandoradsgränssnittet för motsvarande klientdelsramverk. Att stödja ytterligare klientdelsramverk med det här mönstret innebar att lägga till ytterligare logik i ASP.NET Core.
De uppdaterade ASP.NET Core-mallarna för Angular och React i .NET 6 förändrar denna uppsättning och drar nytta av det inbyggda proxystödet hos utvecklingsservrarna för de flesta moderna frontend-ramverk. När ASP.NET Core-appen startas, startas klientdelsutvecklingsservern precis som tidigare, men utvecklingsservern är konfigurerad för att vidarebefordra begäranden till serverdelen i ASP.NET Core-processen. Alla klientdelsspecifika konfigurationer för konfiguration av proxy är en del av appen, inte ASP.NET Core. Det är nu enkelt att konfigurera ASP.NET Core-projekt för att arbeta med andra front-endramverk: konfigurera utvecklingsservern för det valda front-endramverket så att den skickar vidare till ASP.NET Core-serverdelen med mönstret från Angular- och React-mallarna.
Startkoden för ASP.NET Core-appen behöver inte längre någon enskild appspecifik logik. Logiken för att starta utvecklingsservern för klientdelen under utveckling infogas i appen vid körning av det nya Microsoft.AspNetCore.SpaProxy-paketet. Reservroutning hanteras med slutpunktsroutning i stället för SPA-specifik mellanprogramvara.
Mallar som följer det här mönstret kan fortfarande köras som ett enda projekt i Visual Studio eller med hjälp av dotnet run från kommandoraden. När appen publiceras byggs och samlas klientdelskoden sedan in i mappen ClientApp som tidigare, i webbroten för värd-ASP.NET Core-appen, och tjänar som statiska filer. Skript som ingår i mallen konfigurerar klientdelsutvecklingsservern så att den använder HTTPS med hjälp av utvecklingscertifikatet ASP.NET Core.
Förberett stöd för HTTP/3 i .NET 6
HTTP/3 är för närvarande i utkast och kan därför komma att ändras. HTTP/3-stöd i ASP.NET Core släpps inte, det är en förhandsversionsfunktion som ingår i .NET 6.
Se blogginlägget HTTP/3-support i .NET 6.
Nollbara referenstypnoteringar
Delar av ASP.NET Core i .NET 6-källkoden har fått nullbarhetsanteckningar tillämpade.
Genom att använda den nya funktionen Nullable i C# 8 kan ASP.NET Core ge ytterligare kompileringstidssäkerhet vid hantering av referenstyper. Till exempel skydd mot null referensundantag. Projekt som har valt att använda nullbara anteckningar kan se nya build-time-varningar från ASP.NET Core-API:er.
Om du vill aktivera null-referenstyper lägger du till följande egenskap i projektfiler:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
För mer information, se nullbara referenstyper.
Källkodsanalys
Flera .NET-kompilatorplattformsanalyser har lagts till som kontrollerar programkoden efter problem, till exempel felaktig mellanprogramskonfiguration eller ordning, routningskonflikter osv. Mer information finns i Kodanalys i ASP.NET Core-appar.
Förbättringar av mallar för webbappar
Webbappmallarna:
- Använd den nya minimala värdmodellen.
- Minskar avsevärt antalet filer och rader med kod som krävs för att skapa en app. Den tomma webbappen ASP.NET Core skapar till exempel en C#-fil med fyra kodrader och är en komplett app.
- Förenar
Startup.csochProgram.cstill en endaProgram.csfil. - Använder toppnivåinstruktioner för att minimera den kod som krävs för en app.
- Använder globala
usingdirektiv för att eliminera eller minimera antalet instruktionsraderusingsom krävs.
Mallgenererade portar för Kestrel
Slumpmässiga portar tilldelas när projektet skapas för användning av Kestrel webbservern. Slumpmässiga portar hjälper till att minimera en portkonflikt när flera projekt körs på samma dator.
När ett projekt skapas anges en slumpmässig HTTP-port mellan 5000-5300 och en slumpmässig HTTPS-port mellan 7000 och 7300 i den genererade Properties/launchSettings.json filen. Portarna kan ändras i Properties/launchSettings.json filen. Om ingen port har angetts Kestrel används standardportarna HTTP 5000 och HTTPS 5001. Mer information finns i Konfigurera slutpunkter för ASP.NET Core Kestrel-webbservern.
Nya standardinställningar för loggning
Följande ändringar har gjorts i både appsettings.json och appsettings.Development.json:
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
+ "Microsoft.AspNetCore": "Warning"
Ändringen från "Microsoft": "Warning" till "Microsoft.AspNetCore": "Warning" resulterar i loggning av alla informationsmeddelanden från Microsoft namnområdet utomMicrosoft.AspNetCore. Till exempel loggas Microsoft.EntityFrameworkCore nu på informationsnivå.
Utvecklarens undantagssida Mellanprogram läggs till automatiskt
I utvecklingsmiljönDeveloperExceptionPageMiddleware läggs den till som standard. Du behöver inte längre lägga till följande kod i webbgränssnittsappar:
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Stöd för Latin1-kodade begärandehuvuden i HttpSysServer
HttpSysServer stöder nu avkodning av begärandehuvuden som är kodade genom att ställa in egenskapen Latin1 på UseLatin1RequestHeaders till HttpSysOptions:true
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys(o => o.UseLatin1RequestHeaders = true);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
Loggarna för ASP.NET Core-modulen innehåller tidsstämplar och PID
ASP.NET Core Module (ANCM) för IIS (ANCM) förbättrade diagnostikloggar inkluderar tidsstämplar och PID för processen som genererar loggarna. Loggningstidsstämplar och PID gör det enklare att diagnostisera problem med överlappande processomstarter i IIS när flera IIS-arbetsprocesser körs.
De resulterande loggarna liknar nu exempelutdata som visas nedan:
[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: ''
Konfigurerbar storlek på obearbetad inkommande buffert för IIS
IIS-servern buffrade tidigare endast 64 KiB av oförbrukade begärandetext. 64 KiB-buffring resulterade i att läsningar begränsades till den maximala storleken, vilket påverkar prestandan vid stora inkommande datamängder, så som uppladdningar. I .NET 6 ändras standardbuffertstorleken från 64 KiB till 1 MiB, vilket bör förbättra dataflödet för stora uppladdningar. I våra tester tar en 700 MiB-uppladdning som brukade ta 9 sekunder nu bara 2,5 sekunder.
Nackdelen med en större buffertstorlek är en ökad minnesförbrukning per begäran när appen inte snabbt läser från begärandetexten. Förutom att ändra standardbuffertstorleken kan du konfigurera buffertstorleken så att appar kan konfigurera buffertstorleken baserat på arbetsbelastningen.
Visa tagghjälpare för komponenter
Överväg en vykomponent med en valfri parameter, som du ser i följande kod:
class MyViewComponent
{
IViewComponentResult Invoke(bool showSomething = false) { ... }
}
Med ASP.NET Core i .NET 6 kan tagghjälpen anropas utan att du behöver ange ett värde för parametern showSomething :
<vc:my />
Angular-mall uppdaterad till Angular 12
Mallen ASP.NET Core i .NET 6 för Angular använder nu Angular 12.
React-mallen har uppdaterats till React 17.
Konfigurerbart bufferttröskelvärde innan du skriver till disken i Json.NET utdataformaterare
Obs! Vi rekommenderar att du använder System.Text.Json utdataformateraren förutom när serialiseraren Newtonsoft.Json krävs av kompatibilitetsskäl. Serialiseraren System.Text.Json är helt async och fungerar effektivt för större databelastningar.
Utdataformatteraren Newtonsoft.Json buffrar som standard svar upp till 32 KiB i minnet innan det buffras till disken. Detta är för att undvika synkron I/O, vilket kan resultera i andra biverkningar som trådsvältning och programlåsningar. Men om svaret är större än 32 KiB inträffar betydande disk-I/O. Minneströskelvärdet kan nu konfigureras via egenskapen MvcNewtonsoftJsonOptions.OutputFormatterMemoryBufferThreshold innan du buffrar till disken:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages()
.AddNewtonsoftJson(options =>
{
options.OutputFormatterMemoryBufferThreshold = 48 * 1024;
});
var app = builder.Build();
Mer information finns i den här GitHub-pull-begäran och filen NewtonsoftJsonOutputFormatterTest.cs .
Snabbare hämtning och sättning av HTTP-headerar
Nya API:er har lagts till för att exponera alla vanliga rubriker tillgängliga på Microsoft.Net.Http.Headers.HeaderNames som egenskaper på IHeaderDictionary, vilket resulterar i ett enklare att använda API. Till exempel hämtar det infogade mellanprogrammet i följande kod och anger både begärande- och svarshuvuden med hjälp av de nya API:erna:
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();
För implementerade huvuden implementeras get- och set-åtkomsterna genom att gå direkt till fältet och kringgå sökningen. För icke-implementerade huvuden kan åtkomsterna kringgå den första sökningen mot implementerade huvuden och utföra sökningen Dictionary<string, StringValues> direkt. Om du undviker sökningen får du snabbare åtkomst för båda scenarierna.
Asynkron strömning
ASP.NET Core stöder nu asynkron direktuppspelning från kontrollantåtgärder och svar från JSON-formatatorn. När du returnerar en IAsyncEnumerable från en åtgärd buffrar det inte längre svarsinnehållet i minnet innan det skickas. Att undvika buffring hjälper till att minska minnesanvändningen när stora dataset returneras och kan enumereras asynkront.
Observera att Entity Framework Core tillhandahåller implementeringar av IAsyncEnumerable för att köra frågor mot databasen. Det förbättrade stödet för IAsyncEnumerable i ASP.NET Core i .NET 6 kan göra det effektivare att använda EF Core med ASP.NET Core. Följande kod buffrar till exempel inte längre produktdata i minnet innan svaret skickas:
public IActionResult GetMovies()
{
return Ok(_context.Movie);
}
Men när du använder lat inläsning i EF Corekan det här nya beteendet leda till fel på grund av samtidig frågekörning medan data räknas upp. Appar kan återgå till det tidigare beteendet genom att buffring av data:
public async Task<IActionResult> GetMovies2()
{
return Ok(await _context.Movie.ToListAsync());
}
Mer information om den här beteendeförändringen finns i det relaterade tillkännagivandet .
HTTP-loggning mellanprogram
HTTP-loggning är ett nytt inbyggt mellanprogram som loggar information om HTTP-begäranden och HTTP-svar, inklusive rubrikerna och hela brödtexten:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpLogging();
app.MapGet("/", () => "Hello World!");
app.Run();
Navigera till / med föregående kod för att logga information som liknar följande utdata:
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
Föregående utdata aktiverades med följande appsettings.Development.json fil:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information"
}
}
}
HTTP-loggning innehåller loggar med:
- HTTP-begärandeinformation
- Gemensamma egenskaper
- Rubriker
- Kropp
- HTTP-svarsinformation
Om du vill konfigurera mellanprogrammet för HTTP-loggning anger du 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
Begärandefunktionen IConnectionSocketFeature ger åtkomst till den underliggande accept socket som är associerad med den aktuella begäran. Kan nås via FeatureCollection på HttpContext.
Till exempel anger följande app LingerState egenskapen på den godkända socketen.
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();
Allmänna typbegränsningar i Razor
När du definierar allmänna typparametrar i Razor med hjälp av @typeparam direktivet kan du nu ange allmänna typbegränsningar med hjälp av C#-standardsyntaxen:
Mindre SignalR, Blazor Server, och MessagePack-skript
Skripten SignalR, MessagePack och Blazor Server är nu betydligt mindre, vilket möjliggör mindre nedladdningar, mindre JavaScript-parsning och kompilering av webbläsaren och snabbare start. Storleksminskningarna:
-
signalr.js: 70% -
blazor.server.js: 45%
De mindre skripten är ett resultat av ett samhällsbidrag från Ben Adams. Mer information om storleksminskningen finns i Bens GitHub-pull-begäran.
Aktivera Redis-profileringssessioner
Ett community-bidrag från Gabriel Lucaci möjliggör Redis-profileringssession med Microsoft.Extensions.Caching.StackExchangeRedis:
using StackExchange.Redis.Profiling;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ProfilingSession = () => new ProfilingSession();
});
Mer information finns i StackExchange.Redis-profilering.
Skuggkopiering i IIS
En experimentell funktion har lagts till i ASP.NET Core Module (ANCM) för IIS för att lägga till stöd för programsammansättningar för skuggkopiering. För närvarande låser .NET programbinärfiler när de körs i Windows, vilket gör det omöjligt att ersätta binärfiler när appen körs. Även om vår rekommendation fortfarande är att använda en app offlinefil, inser vi att det finns vissa scenarier (till exempel FTP-distributioner) där det inte är möjligt att göra det.
I sådana scenarier aktiverar du skuggkopiering genom att anpassa inställningarna för ASP.NET Core-modulhanterare. I de flesta fall har ASP.NET Core-appar inte någon web.config incheckad källkontroll som du kan ändra. I ASP.NET Core web.config genereras vanligtvis av SDK:et. Följande exempel web.config kan användas för att komma igång:
<?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>
Skuggkopiering i IIS är en experimentell funktion som inte garanteras vara en del av ASP.NET Core. Lämna feedback om IIS Shadow-kopiering i det här GitHub-problemet.
Brytande förändringar
Använd artiklarna i Icke-bakåtkompatibla ändringar i .NET för att hitta icke-bakåtkompatibla ändringar som kan gälla när du uppgraderar en app till en nyare version av .NET.
Ytterligare resurser
ASP.NET Core