Nyheter i ASP.NET Core 8.0
Den här artikeln belyser de viktigaste ändringarna i ASP.NET Core 8.0 med länkar till relevant dokumentation.
Blazor
Full-stack webb-användargränssnitt
Med lanseringen av .NET 8 är Blazor ett fullständigt webbgränssnittsramverk för utveckling av appar som renderar innehåll på komponent- eller sidnivå med:
- Statisk serverrendering (kallas även statisk återgivning på serversidan, statisk SSR) för att generera statisk HTML på servern.
- Interaktiv serverrendering (kallas även interaktiv återgivning på serversidan, interaktiv SSR) för att generera interaktiva komponenter med prerendering på servern.
- Interaktiv WebAssembly-återgivning (kallas även återgivning på klientsidan, CSR, som alltid antas vara interaktiv) för att generera interaktiva komponenter på klienten med prerendering på servern.
- Interaktiv automatisk återgivning för att initialt använda ASP.NET Core-körning på serversidan för innehållsrendering och interaktivitet. .NET WebAssembly-körningen på klienten används för efterföljande återgivning och interaktivitet efter att Blazor-paketet har laddats ned och WebAssembly-körningen aktiveras. Interaktiv automatisk återgivning ger vanligtvis den snabbaste startupplevelsen för appar.
Interaktiva återgivningslägen föråterger också innehåll som förval.
Mer information finns i följande artiklar:
- ASP.NET Core: Grunderna Blazor: Nya avsnitt om rendering och statiska/interaktiva koncept visas överst i artikeln.
- ASP.NET Core Blazor återgivningslägen
- Migreringstäckning: Migrera från ASP.NET Core 7.0 till 8.0
Exempel i hela Blazor dokumentationen har uppdaterats för användning i Blazor Web Apps. Blazor Server-exempel finns kvar i innehåll som är versionerat för .NET 7 eller tidigare.
Ny artikel om klassbibliotek med statisk återgivning på serversidan (statisk SSR)
Vi har lagt till en ny artikel som beskriver redigering av komponentbibliotek i Razor klassbibliotek (RCL) med statisk återgivning på serversidan (statisk SSR).
Mer information finns i ASP.NET Core Razor-klassbibliotek (RCLs) med statisk serveråtergivning (statisk SSR).
Ny artikel om problem med HTTP-cachelagring
Vi har lagt till en ny artikel som beskriver några av de vanliga problem med HTTP-cachelagring som kan uppstå när du uppgraderar Blazor appar i större versioner och hur du åtgärdar problem med HTTP-cachelagring.
Mer information finns i Undvik problem med HTTP-cachelagring när du uppgraderar ASP.NET Core Blazor-appar.
Ny Blazor Web App mall
Vi har introducerat en ny Blazor projektmall: mallen Blazor Web App. Den nya mallen ger en enda startpunkt för att använda Blazor komponenter för att skapa alla typer av webbgränssnitt. Mallen kombinerar de befintliga Blazor Server och Blazor WebAssembly värdmodeller med de nya Blazor funktionerna som lagts till i .NET 8: statisk återgivning på serversidan (statisk SSR), återgivning av direktuppspelning, förbättrad navigering och formulärhantering samt möjligheten att lägga till interaktivitet med hjälp av antingen Blazor Server eller Blazor WebAssembly per komponent.
Som en del av att förena de olika Blazor värdmodeller till en enda modell i .NET 8 konsoliderar vi också antalet Blazor projektmallar. Vi har tagit bort mallen Blazor Server och alternativet ASP.NET Core Hosted har tagits bort från mallen Blazor WebAssembly. Båda dessa scenarier representeras av alternativ när du använder mallen Blazor Web App.
Not
Befintliga Blazor Server- och Blazor WebAssembly-appar stöds fortfarande i .NET 8. Valfritt kan dessa appar uppdateras så att de använder det nya fullstack-webbgränssnittets Blazor funktioner.
Mer information om den nya mallen Blazor Web App finns i följande artiklar:
Nya JS-initialiserare för Blazor Web App-enheter
För Blazor Server, Blazor WebAssemblyoch Blazor Hybrid appar:
-
beforeStart
används för uppgifter som att anpassa inläsningsprocessen, loggningsnivån och andra alternativ. -
afterStarted
används för uppgifter som att registrera Blazor händelselyssnare och anpassade händelsetyper.
Äldre JS initierare anropas inte som standard i en Blazor Web App. För Blazor Web Apps används en ny uppsättning JS initierare: beforeWebStart
, afterWebStarted
, beforeServerStart
, afterServerStarted
, beforeWebAssemblyStart
och afterWebAssemblyStarted
.
Mer information finns i ASP.NET Core Blazor start.
Uppdelning av vägledning för förberäkning och integrering
För tidigare versioner av .NET har vi gått igenom prerendering och integrering i en enda artikel. För att förenkla och fokusera vår täckning har vi delat upp ämnena i följande nya artiklar, som har uppdaterats för .NET 8:
- Prerender ASP.NET Core-komponenter Razor
- Integrera ASP.NET Core Razor-komponenter med MVC- eller Razor Pages-
Behåll komponenttillstånd i en Blazor Web App
Du kan bevara och läsa komponenttillstånd i en Blazor Web App med hjälp av den befintliga PersistentComponentState-tjänsten. Detta är användbart för bestående komponenttillstånd under.
Blazor Web Apps bevarar automatiskt alla registrerade tillstånd på appnivå som skapats under den förberedande renderingen, vilket tar bort behovet av taggassistenten för bevarande av komponenttillstånd.
Formulärhantering och modellbindning
Blazor komponenter kan nu hantera skickade formulärbegäranden, inklusive modellbindning och validering av begärandedata. Komponenter kan implementera formulär med separata formulärhanterare med hjälp av html-standardtaggen <form>
eller med hjälp av den befintliga EditForm
komponenten.
Formmodellbindning i Blazor respekterar datakontraktsattributen (till exempel [DataMember]
och [IgnoreDataMember]
) för att anpassa hur formulärdata är bundna till modellen.
Nytt stöd för falskningsskydd ingår i .NET 8. En ny AntiforgeryToken
-komponent renderar en antiforgery-token som ett dolt fält, och det nya attributet [RequireAntiforgeryToken]
aktiverar skydd mot förfalskning. Om en antiforgery-kontroll misslyckas returneras ett svar på 400 (felaktig begäran) utan formulärbearbetning. De nya funktionerna för skydd mot förfalskning är aktiverade som standard för formulär baserat på Editform
och kan tillämpas manuellt på STANDARD-HTML-formulär.
För mer information, se översikten över ASP.NET Core Blazor-formulär.
Förbättrad navigering och formulärhantering
Statisk återgivning på serversidan (statisk SSR) utför vanligtvis en fullständig siduppdatering när användaren navigerar till en ny sida eller skickar ett formulär. I .NET 8 kan Blazor förbättra sidnavigeringen och formulärhanteringen genom att fånga upp begäran och utföra en hämtningsbegäran i stället.
Blazor hanterar sedan det renderade svarsinnehållet genom att korrigera det till webbläsarens DOM. Förbättrad navigering och formulärhantering undviker behovet av en fullständig siduppdatering och bevarar mer av sidtillståndet, så att sidorna läses in snabbare och smidigare. Förbättrad navigering aktiveras som standard när skriptet Blazor (blazor.web.js
) läses in. Förbättrad formulärhantering kan eventuellt aktiveras för specifika formulär.
Med det nya förbättrade navigerings-API:et kan du uppdatera den aktuella sidan genom att anropa NavigationManager.Refresh(bool forceLoad = false)
.
Mer information finns i följande avsnitt i artikeln BlazorRoutning:
Ny artikel om statisk rendering med förbättrad navigering för JS interop
Vissa appar är beroende av JS interop för att utföra initieringsuppgifter som är specifika för varje sida. När du använder Blazorförbättrade navigeringsfunktionen med statiskt renderade sidor som utför JS interop-initieringsuppgifter kan det hända att sidspecifika JS inte körs igen som förväntat varje gång en förbättrad sidnavigering sker. En ny artikel beskriver hur du hanterar det här scenariot i Blazor Web Apps:
ASP.NET Core Blazor JavaScript med statisk återgivning på serversidan (statisk SSR)
Streaming-återgivning
Nu kan du strömma innehållsuppdateringar på svarsströmmen när du använder statisk återgivning på serversidan (statisk SSR) med Blazor. Strömningsrendering kan förbättra användarupplevelsen för sidor som utför långvariga asynkrona uppgifter genom att rendera innehåll så snart det är tillgängligt, vilket leder till en fullständig återgivning.
Om du till exempel vill återge en sida kan du behöva göra en tidskrävande databasfråga eller ett API-anrop. Normalt måste asynkrona uppgifter som körs som en del av återgivningen av en sida slutföras innan det renderade svaret skickas, vilket kan fördröja inläsningen av sidan. Direktuppspelning återger inledningsvis hela sidan med platshållarinnehåll medan asynkrona åtgärder körs. När de asynkrona åtgärderna har slutförts skickas det uppdaterade innehållet till klienten via samma svarsanslutning och infogas i DOM. Fördelen med den här metoden är att appens huvudlayout återges så snabbt som möjligt och att sidan uppdateras så snart innehållet är klart.
För mer information, se ASP.NET Core Razor komponentåtergivning.
Mata in nyckelade tjänster i komponenter
Blazor stöder nu inmatning av nyckelade tjänster med hjälp av attributet [Inject]
. Nycklar möjliggör begränsning av registrering och konsumtion av tjänster när du använder dependency injection. Använd den nya egenskapen InjectAttribute.Key
för att ange nyckeln för tjänsten som ska matas in:
[Inject(Key = "my-service")]
public IMyService MyService { get; set; }
@inject
Razor-direktivet stöder inte nyckelade tjänster för den här versionen, men arbetet spåras av Update @inject
för att stödja nyckelade tjänster (dotnet/razor #9286) för en framtida .NET-version.
Mer information finns i ASP.NET Core Blazor beroendeinjektion.
Åtkomst HttpContext
som en kaskaderande parameter
Nu kan du komma åt den aktuella HttpContext som en sammanhängande parameter från en statisk serverkomponent:
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
Det kan vara användbart att komma åt HttpContext från en statisk serverkomponent för att inspektera och ändra rubriker eller andra egenskaper.
Ett exempel som skickar HttpContext tillstånd, åtkomst och uppdateringstoken till komponenter finns i ASP.NET Core-serversidan och Blazor Web App ytterligare säkerhetsscenarier.
Rendera Razor komponenter utanför ASP.NET Core
Nu kan du rendera Razor komponenter utanför kontexten för en HTTP-begäran. Du kan återge Razor-komponenter som HTML direkt till en sträng eller ström, oberoende av ASP.NET Core - värdmiljön. Detta är praktiskt för scenarier där du vill generera HTML-fragment, till exempel för att generera e-post eller statiskt webbplatsinnehåll.
Mer information finns i Rendera Razor-komponenter utanför ASP.NET Core.
Stöd för avsnitt
De nya komponenterna SectionOutlet
och SectionContent
i Blazor lägga till stöd för att ange utlopp för innehåll som kan fyllas i senare. Avsnitt används ofta för att definiera platshållare i layouter som sedan fylls i av specifika sidor. Avsnitt refereras antingen till med ett unikt namn eller med hjälp av ett unikt objekt-ID.
Mer information finns i avsnitten ASP.NET Core Blazor.
Support för felsidor
En anpassad felsida kan definieras av Blazor Web Appför användning med ASP.NET Core-undantagshanteringsmellanvaran.
Blazor Web App-projektmallen innehåller en standardfelsida (Components/Pages/Error.razor
) med liknande innehåll som den som används i MVC- och Razor Pages-appar. När felsidan återges som svar på en begäran från Undantagshantering av mellanprogram återges alltid felsidan som en statisk serverkomponent, även om interaktivitet annars är aktiverat.
Error.razor
i referenskällan 8.0
QuickGrid
Blazor QuickGrid-komponenten är inte längre experimentell och är nu en del av Blazor ramverket i .NET 8.
QuickGrid är en rutnätskomponent med höga prestanda för att visa data i tabellform. QuickGrid är byggt för att vara ett enkelt och bekvämt sätt att visa dina data, samtidigt som det erbjuder kraftfulla funktioner som sortering, filtrering, paginering och virtualisering.
Mer information finns i ASP.NET Core Blazor QuickGrid-komponenten.
Rikta till namngivna element
Blazor stöder nu användning av routning på klientsidan för att navigera till ett specifikt HTML-element på en sida med hjälp av standard-URL-fragment. Om du anger en identifierare för ett HTML-element med standardattributet id
rullar Blazor korrekt till elementet när URL-fragmentet matchar elementidentifieraren.
Mer information finns i ASP.NET Core Blazor routning och navigering.
Sammanhängande värden på rotnivå
Sammanhängande värden på rotnivå kan registreras för hela komponenthierarkin. Namngivna sammanhängande värden och prenumerationer för uppdateringsmeddelanden stöds.
Mer information finns i ASP.NET Core Blazor sammanhängande värden och parametrar.
Virtualisera tomt innehåll
Använd den nya EmptyContent
-parametern på komponenten Virtualize
för att ange innehåll när komponenten har lästs in och antingen Items
är tom eller ItemsProviderResult<T>.TotalItemCount
är noll.
Mer information finns i ASP.NET Core Razor-komponentvirtualisering.
Stäng kretsar när det inte finns några återstående interaktiva serverkomponenter
Interaktiva serverkomponenter hanterar webbgränssnittshändelser med hjälp av en realtidsanslutning med webbläsaren som kallas för en krets. En krets och dess tillhörande tillstånd konfigureras när en rotkomponent för interaktiva servrar renderas. Kretsen stängs när det inte finns några återstående interaktiva serverkomponenter på sidan, vilket frigör serverresurser.
Övervaka SignalR kretsaktivitet
Nu kan du övervaka inkommande kretsaktivitet i appar på serversidan med hjälp av den nya CreateInboundActivityHandler
-metoden på CircuitHandler
. Inkommande kretsaktivitet är en aktivitet som skickas från webbläsaren till servern, till exempel användargränssnittshändelser eller JavaScript-to-.NET interop-anrop.
Mer information finns i ASP.NET Core BlazorSignalR vägledning.
Snabbare körningsprestanda med Jiterpreter
Jiterpreter är en ny körningsfunktion i .NET 8 som möjliggör partiellt JIT-kompileringsstöd (Just-in-Time) när du kör webAssembly för att få bättre körningsprestanda.
Mer information finns i Värd och distribuera ASP.NET Core Blazor WebAssembly.
I förväg (AOT) SIMD och undantagshantering
Blazor WebAssembly förkompilering (AOT) använder nu som standard WebAssembly fast bredd SIMD och WebAssembly-undantagshantering för att förbättra körningsprestanda.
Mer information finns i följande artiklar:
Webvänlig Webcil-paketering
Webcil är en webvänlig paketering av .NET-sammansättningar som tar bort innehåll som är specifikt för intern Windows-körning för att undvika problem vid distribution till miljöer som blockerar nedladdning eller användning av .dll
filer. Webcil är aktiverat som standard för Blazor WebAssembly appar.
Mer information finns i Värd och distribuera ASP.NET Core Blazor WebAssembly.
Not
Före lanseringen av .NET 8 finns vägledning i Distributionslayout för ASP.NET Core-värd Blazor WebAssembly applikationer som adresserar miljöer där klienter blockeras från att ladda ned och köra DLL:er genom en metod med flerdelspaketering. I .NET 8 eller senare använder Blazor filformatet Webcil för att lösa problemet. Flerdelspaket med hjälp av det experimentella NuGet-paketet som beskrivs i WebAssembly-distributionslayouten artikeln stöds inte för Blazor-appar i .NET 8 eller senare. För mer information, se Förbättra Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
paketet för att definiera ett anpassat buntformat (dotnet/aspnetcore #36978). Om du vill fortsätta använda paketpaketet för flera delar i .NET 8 eller senare appar kan du använda vägledningen i artikeln för att skapa ett eget NuGet-paket med flera delar, men det stöds inte av Microsoft.
Blazor WebAssembly felsökningsförbättringar
När du felsöker .NET på WebAssembly laddar felsökningsprogrammet nu ned symboldata från symbolplatser som har konfigurerats i Visual Studio-inställningar. Detta förbättrar felsökningsupplevelsen för appar som använder NuGet-paket.
Nu kan du felsöka Blazor WebAssembly appar med Firefox. Felsökning av Blazor WebAssembly-appar kräver att webbläsaren konfigureras för fjärrfelsökning och att man sedan ansluter till webbläsaren med hjälp av utvecklarverktygen för webbläsaren via .NET WebAssembly-felsökningsproxyn. Felsökning av Firefox från Visual Studio stöds inte just nu.
Mer information finns i Felsöka ASP.NET Core Blazor-appar.
CSP-kompatibilitet (Content Security Policy)
Blazor WebAssembly kräver inte längre att du aktiverar unsafe-eval
skriptkälla när du anger en innehållssäkerhetsprincip (CSP).
Mer information finns i Framtvinga en innehållssäkerhetsprincip för ASP.NET Core Blazor.
Hantera fångade undantag utanför livscykeln för en Razor-komponent
Använd ComponentBase.DispatchExceptionAsync
i en Razor komponent för att bearbeta undantag som genereras utanför komponentens livscykelanropsstack. Detta gör att komponentens kod kan behandla undantag som om de är undantag för livscykelmetoder. Därefter kan Blazorfelhanteringsmekanismer, till exempel felgränser, bearbeta undantag.
Mer information finns i Hantera fel i ASP.NET Core Blazor-appar.
Konfigurera .NET WebAssembly-körtidsmiljön
.NET WebAssembly-körmiljön kan nu konfigureras för Blazor start.
Mer information finns i ASP.NET Core Blazor start.
Konfiguration av tidsgränser för anslutningar i HubConnectionBuilder
Tidigare lösningar för att konfigurera tidsgränser för hubbanslutningar kan ersättas med formell timeout-konfiguration för SignalR hubbanslutningsbyggare.
Mer information finns i följande:
- ASP.NET Core BlazorSignalR vägledning
- Värd och distribuera ASP.NET Core Blazor WebAssembly
- Värd och distribuera ASP.NET Core-Blazor appar på serversidan
Projektmallar överger Open Iconic
De Blazor projektmallarna är inte längre beroende av Open Iconic för ikoner.
Stöd för att avbryta och stänga händelser i dialogrutan
Blazor stöder nu cancel
- och close
-händelserna i html-elementet dialog
.
I följande exempel:
-
OnClose
anropas när dialogrutanmy-dialog
stängs med knappen Stäng. -
OnCancel
anropas när dialogrutan avbryts med nyckeln Esc. När en HTML-dialogruta stängs med nyckeln Esc utlöses bådecancel
- ochclose
-händelserna.
<div>
<p>Output: @message</p>
<button onclick="document.getElementById('my-dialog').showModal()">
Show modal dialog
</button>
<dialog id="my-dialog" @onclose="OnClose" @oncancel="OnCancel">
<p>Hi there!</p>
<form method="dialog">
<button>Close</button>
</form>
</dialog>
</div>
@code {
private string? message;
private void OnClose(EventArgs e) => message += "onclose, ";
private void OnCancel(EventArgs e) => message += "oncancel, ";
}
Blazor Identity användargränssnitt
Blazor stöder generering av ett fullständigt Blazor-baserat Identity-användargränssnitt när du väljer autentiseringsalternativet för individuella konton. Du kan antingen välja alternativet för Enskilda konton i dialogrutan för det nya projektet för Blazor Web Appfrån Visual Studio eller skicka alternativet -au|--auth
inställt på Individual
från kommandoraden när du skapar ett nytt projekt.
Mer information finns i följande resurser:
Skydda Blazor WebAssembly med ASP.NET Core Identity
Den Blazor-dokumentationen innehåller en ny artikel och exempelapp om att säkra en fristående app för Blazor WebAssembly med ASP.NET Core Identity.
Mer information finns i följande resurser:
- Secure ASP.NET Core Blazor WebAssembly med ASP.NET Core Identity
- Nyheter med identitet i .NET 8 (blogginlägg)
Blazor Server med Yarp-routning
Routning och djuplänkning för Blazor Server med Yarp fungerar korrekt i .NET 8.
Mer information finns i Migrera från ASP.NET Core 7.0 till 8.0.
Flera Blazor Web Appper serverprojekt
Stöd för flera Blazor Web Appper server-projekt kommer att övervägas för .NET 10 (november 2025).
För mer information, se stöd för flera Blazor webbappar per serverprojekt (dotnet/aspnetcore
#52216).
Blazor Hybrid
Följande artiklar dokumenterar ändringar för Blazor Hybrid i .NET 8:
- Felsöka ASP.NET Core Blazor Hybrid: I en ny artikel beskrivs användningen av BlazorWebView loggning.
- Skapa en .NET MAUIBlazor Hybrid app: Namnet på projektmallen .NET MAUI Blazor har ändrats till .NET MAUI Blazor Hybrid.
-
ASP.NET Core Blazor Hybrid:
BlazorWebView
får enTryDispatchAsync
metod som anropar en angivenAction<ServiceProvider>
asynkront och skickar de omfångstjänster som är tillgängliga i Razor komponenter. Detta gör att kod från det interna användargränssnittet kan komma åt begränsade tjänster, till exempelNavigationManager
. -
ASP.NET Core Blazor Hybrid ruttning och navigering: Använd egenskapen
BlazorWebView.StartPath
för att hämta eller ange sökvägen för inledande navigering inom Blazor navigeringskontexten när Razor komponenten har lästs in.
[Parameter]
attributet krävs inte längre när det tillhandahålls från frågesträngen
Attributet [Parameter]
krävs inte längre när du anger en parameter från frågesträngen:
- [Parameter]
[SupplyParameterFromQuery]
SignalR
Ny metod för att ange tidsgränsen för servern och Keep-Alive intervall
ServerTimeout (standard: 30 sekunder) och KeepAliveInterval (standard: 15 sekunder) kan ställas in direkt på HubConnectionBuilder.
Tidigare metod för JavaScript-klienter
I följande exempel visas tilldelningen av värden som är dubbla standardvärdena i ASP.NET Core 7.0 eller tidigare:
var connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.build();
connection.serverTimeoutInMilliseconds = 60000;
connection.keepAliveIntervalInMilliseconds = 30000;
Ny metod för JavaScript-klienter
I följande exempel visas den nya metoden för att tilldela värden som är dubbla standardvärdena i ASP.NET Core 8.0 eller senare:
var connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.withServerTimeout(60000)
.withKeepAlive(30000)
.build();
Tidigare metod för JavaScript-klienten för en Blazor Server-app
I följande exempel visas tilldelningen av värden som är dubbla standardvärdena i ASP.NET Core 7.0 eller tidigare:
Blazor.start({
configureSignalR: function (builder) {
let c = builder.build();
c.serverTimeoutInMilliseconds = 60000;
c.keepAliveIntervalInMilliseconds = 30000;
builder.build = () => {
return c;
};
}
});
Ny metod för JavaScript-klienten för Blazor-appen på serversidan
I följande exempel visas den nya metoden för att tilldela värden som är dubbla standardvärdena i ASP.NET Core 8.0 eller senare för Blazor Web Apps och Blazor Server.
Blazor Web App:
Blazor.start({
circuit: {
configureSignalR: function (builder) {
builder.withServerTimeout(60000).withKeepAliveInterval(30000);
}
}
});
Blazor Server:
Blazor.start({
configureSignalR: function (builder) {
builder.withServerTimeout(60000).withKeepAliveInterval(30000);
}
});
Tidigare metod för .NET-klienter
I följande exempel visas tilldelningen av värden som är dubbla standardvärdena i ASP.NET Core 7.0 eller tidigare:
var builder = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.Build();
builder.ServerTimeout = TimeSpan.FromSeconds(60);
builder.KeepAliveInterval = TimeSpan.FromSeconds(30);
builder.On<string, string>("ReceiveMessage", (user, message) => ...
await builder.StartAsync();
Ny metod för .NET-klienter
I följande exempel visas den nya metoden för att tilldela värden som är dubbla standardvärdena i ASP.NET Core 8.0 eller senare:
var builder = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.WithServerTimeout(TimeSpan.FromSeconds(60))
.WithKeepAliveInterval(TimeSpan.FromSeconds(30))
.Build();
builder.On<string, string>("ReceiveMessage", (user, message) => ...
await builder.StartAsync();
SignalR tillståndskänslig återanslutning
SignalR tillståndsbevarande återanslutning minskar den upplevda nedtiden för klienter som upplever en tillfällig frånkoppling i sin nätverksanslutning, till exempel vid byte av nätverksanslutning eller ett kortvarigt avbrott i åtkomsten.
Tillståndsbevarande återanslutning uppnår detta genom att:
- Buffrar tillfälligt data på servern och klienten.
- Bekräfta mottagna meddelanden (ACK-ing) av både servern och klienten.
- Identifierar när en anslutning returnerar och spelar upp meddelanden som kan ha skickats när anslutningen var nere.
Tillståndskänslig återanslutning är tillgängligt i ASP.NET Core 8.0 och senare.
Aktivera tillståndsberoende återanslutning vid både server-hubbens slutpunkt och klienten.
Uppdatera serverhubbens slutpunktskonfiguration för att aktivera alternativet
AllowStatefulReconnects
:app.MapHub<MyHub>("/hubName", options => { options.AllowStatefulReconnects = true; });
Du kan också ange den maximala buffertstorleken i byte som tillåts av servern globalt eller för en specifik hubb med alternativet
StatefulReconnectBufferSize
:Alternativet
StatefulReconnectBufferSize
är inställt globalt.builder.AddSignalR(o => o.StatefulReconnectBufferSize = 1000);
Alternativet
StatefulReconnectBufferSize
för en specifik hubb:builder.AddSignalR().AddHubOptions<MyHub>(o => o.StatefulReconnectBufferSize = 1000);
Alternativet
StatefulReconnectBufferSize
är valfritt med standardvärdet 100 000 byte.Uppdatera JavaScript- eller TypeScript-klientkoden för att aktivera alternativet
withStatefulReconnect
:const builder = new signalR.HubConnectionBuilder() .withUrl("/hubname") .withStatefulReconnect({ bufferSize: 1000 }); // Optional, defaults to 100,000 const connection = builder.build();
Alternativet
bufferSize
är valfritt med standardvärdet 100 000 byte.Uppdatera .NET-klientkoden för att aktivera alternativet
WithStatefulReconnect
:var builder = new HubConnectionBuilder() .WithUrl("<hub url>") .WithStatefulReconnect(); builder.Services.Configure<HubConnectionOptions>(o => o.StatefulReconnectBufferSize = 1000); var hubConnection = builder.Build();
Alternativet
StatefulReconnectBufferSize
är valfritt med standardvärdet 100 000 byte.
Mer information finns i Konfigurera tillståndskänslig återanslutning.
Minimala API:er
I det här avsnittet beskrivs nya funktioner för minimala API:er. Se även avsnittet om Native AOT för mer information relevanta för minimala API:er.
Kultur för åsidosättning av användare
Från och med ASP.NET Core 8.0 gör egenskapen RequestLocalizationOptions.CultureInfoUseUserOverride att programmet kan avgöra om icke-standard Windows-inställningar för CultureInfoDateTimeFormat och NumberFormat ska användas eller inte. Detta påverkar inte Linux. Detta motsvarar direkt UseUserOverride.
app.UseRequestLocalization(options =>
{
options.CultureInfoUseUserOverride = false;
});
Bindning till formulär
Explicit bindning till formulärvärden med hjälp av attributet [FromForm] stöds nu. Parametrar som är kopplade till begäran med [FromForm]
inkluderar en antiförfalsknings-token. Antiforgery-token verifieras när begäran bearbetas.
Härledda bindningar till formulär med hjälp av IFormCollection, IFormFileoch IFormFileCollection typer stöds också. OpenAPI- metadata härleds automatiskt för formulärparametrar för att stödja integrering med Swagger UI.
Mer information finns i:
- Explicit bindning från formulärvärden.
- Bindning till formulär med IFormCollection, IFormFile och IFormFileCollection.
- Formulärbindning i minimala API:er
Bindning från formulär stöds nu för:
- Samlingar, till exempel List och Dictionary
- Komplexa typer, till exempel
Todo
ellerProject
Mer information finns i Bind till samlingar och komplexa typer från formulär.
Antiförfalskning med minimala API:er
Den här versionen lägger till ett middleware för validering av antiforgery-tokens, som används för att motverka cross-site request forgery-attacker. Anropa AddAntiforgery för att registrera tjänster för skydd mot förfalskning i DI.
WebApplicationBuilder
lägger automatiskt till mellanprogrammet när antiforgery-tjänsterna har registrerats i DI-containern. Antiforgery-token används för att minimera förfalskningsattacker mellan webbplatser.
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", () => "Hello World!");
app.Run();
Antiforgery-mellanprogrammet:
- Kortsluter inte körningen av resten av begärans pipeline.
- Ställer in IAntiforgeryValidationFeature i HttpContext.Features för den aktuella begäran.
Antiforgery-token verifieras endast om:
- Slutpunkten innehåller metadata som implementerar IAntiforgeryMetadata där
RequiresValidation=true
. - HTTP-metoden som är associerad med slutpunkten är en relevant HTTP-metod. De relevanta metoderna är alla HTTP-metoder förutom TRACE, OPTIONS, HEAD och GET.
- Begäran är associerad med en giltig slutpunkt.
För mer information, se Förfalskningsskydd med minimala API:er.
Nytt IResettable
-gränssnitt i ObjectPool
Microsoft.Extensions.ObjectPool har stöd för att poola objektinstanser i minnet. Appar kan använda en objektpool om värdena är dyra att allokera eller initiera.
I den här versionen har vi gjort objektpoolen enklare att använda genom att lägga till IResettable-gränssnittet. Återanvändbara typer måste ofta återställas till ett standardtillstånd mellan användningarna.
IResettable
typer återställs automatiskt när de returneras till en objektpool.
Mer information finns i ObjectPool-exempel.
Inbyggd AOT
Stöd för .NET native ahead-of-time (AOT) har lagts till. Appar som publiceras med AOT kan ha betydligt bättre prestanda: mindre appstorlek, mindre minnesanvändning och snabbare starttid. Intern AOT stöds för närvarande av gRPC, minimala API- och arbetstjänstappar. Mer information finns i ASP.NET Core-stöd för Native AOT och handledning: Publicera en ASP.NET Core-app med Native AOT. Information om kända problem med ASP.NET Core- och intern AOT-kompatibilitet finns i GitHub-problem dotnet/core #8288.
Bibliotek och intern AOT
Många av de populära bibliotek som används i ASP.NET Core-projekt har för närvarande vissa kompatibilitetsproblem när de används i ett projekt som riktar sig till intern AOT, till exempel:
- Använd reflektion för att inspektera och identifiera typer.
- Villkorlig inläsning av bibliotek under körningstid.
- Generera kod i farten för att implementera funktioner.
Bibliotek som använder dessa dynamiska funktioner måste uppdateras för att fungera med intern AOT. De kan uppdateras med hjälp av verktyg som Roslyn-källgeneratorer.
Biblioteksförfattare som hoppas kunna stödja native AOT uppmuntras att:
Ny projektmall
Den nya ASP.NET Core Web API (Native AOT)-projektmallen (kort namn webapiaot
) skapar ett projekt med AOT-publicering aktiverat. Mer information finns i Webb-API (Native AOT)-mallen.
Ny CreateSlimBuilder
-metod
Den CreateSlimBuilder()-metod som används i webb-API-mallen (Native AOT) initierar WebApplicationBuilder med de minsta ASP.NET Core-funktionerna som krävs för att köra en app. Metoden CreateSlimBuilder
innehåller följande funktioner som vanligtvis behövs för en effektiv utvecklingsupplevelse:
- JSON-filkonfiguration för
appsettings.json
ochappsettings.{EnvironmentName}.json
. - Konfiguration av användarhemligheter.
- Konsolloggning.
- Loggningskonfiguration.
För mer information, se metoden CreateSlimBuilder
.
Ny CreateEmptyBuilder
-metod
Det finns en annan ny WebApplicationBuilder fabriksmetod för att skapa små appar som bara innehåller nödvändiga funktioner: WebApplication.CreateEmptyBuilder(WebApplicationOptions options)
. Den här WebApplicationBuilder
har skapats utan inbyggt beteende. Appen som skapas innehåller endast de tjänster och mellanprogram som uttryckligen har konfigurerats.
Här är ett exempel på hur du använder det här API:et för att skapa ett litet webbprogram:
var builder = WebApplication.CreateEmptyBuilder(new WebApplicationOptions());
builder.WebHost.UseKestrelCore();
var app = builder.Build();
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Hello, World!");
await next(context);
});
Console.WriteLine("Running...");
app.Run();
Publicering av den här koden med intern AOT med .NET 8 Preview 7 på en linux-x64-dator resulterar i en fristående intern körbar fil på cirka 8,5 MB.
Minskad appstorlek med konfigurerbart HTTPS-stöd
Vi har ytterligare minskat den interna AOT-binära storleken för appar som inte behöver HTTPS- eller HTTP/3-stöd. Det är vanligt att inte använda HTTPS eller HTTP/3 för appar som körs bakom en TLS-avslutningsproxy (till exempel i Azure). Den nya metoden WebApplication.CreateSlimBuilder
utelämnar den här funktionen som standard. Det kan läggas till genom att anropa builder.WebHost.UseKestrelHttpsConfiguration()
för HTTPS eller builder.WebHost.UseQuic()
för HTTP/3. För mer information, se metoden CreateSlimBuilder
.
JSON-serialisering av kompilatorgenererade IAsyncEnumerable<T>
typer
Nya funktioner har lagts till i System.Text.Json för att bättre stödja intern AOT. Dessa nya funktioner lägger till funktioner för källgenereringsläget för System.Text.Json
eftersom reflektion inte stöds av AOT.
En av de nya funktionerna är stöd för JSON-serialisering av IAsyncEnumerable<T> implementeringar som implementeras av C#-kompilatorn. Det här stödet öppnar deras användning i ASP.NET Core-projekt som konfigurerats för att publicera intern AOT.
Det här API:et är användbart i scenarier där en routningshanterare använder yield return
för att asynkront returnera en uppräkning. Till exempel för att materialisera rader från en databasfråga. Mer information finns i Stöd för onämnbar typ i tillkännagivandet .NET 8 Preview 4.
Information om andra förbättringar i System.Text.Json
källgenerering finns i Serialiseringsförbättringar i .NET 8.
API:er på toppnivå som har kommenterats för varningar vid trimning
De viktigaste startpunkterna för undersystem som inte fungerar tillförlitligt med intern AOT kommenteras nu. När dessa metoder anropas från ett program med inbyggd AOT-aktiverad visas en varning. Följande kod ger till exempel en varning vid anropet av AddControllers
eftersom det här API:et inte är trimsäkert och inte stöds av intern AOT.
Begära ombudsgenerator
För att göra minimala API:er kompatibla med intern AOT introducerar vi RDG (Request Delegate Generator). RDG är en källgenerator som gör vad RequestDelegateFactory (RDF) gör. Det vill säga: den omvandlar de olika MapGet()
, MapPost()
och anrop som dessa till RequestDelegate-instanser som är associerade med de angivna vägar. Men i stället för att göra det i minnet i ett program när det startar, gör RDG det vid kompileringstid och genererar C#-kod direkt i projektet. Den RDG:
- Tar bort generering vid körning av den här koden.
- Säkerställer att de typer som används i API:er kan analyseras statiskt av den interna AOT-verktygskedjan.
- Ser till att nödvändig kod inte trimmas bort.
Vi arbetar för att se till att så många som möjligt av de minimala API-funktionerna stöds av RDG och därmed är kompatibla med intern AOT.
RDG aktiveras automatiskt i ett projekt när publicering med intern AOT aktiveras. RDG kan aktiveras manuellt även om du inte använder intern AOT genom att ange <EnableRequestDelegateGenerator>true</EnableRequestDelegateGenerator>
i projektfilen. Detta kan vara användbart när du först utvärderar ett projekts beredskap för intern AOT eller för att minska starttiden för en app.
Förbättrad prestanda med interceptorer
Generatorn för begärandedelegat använder den nya kompilatorfunktionen C# 12-kompilatorer för att stödja avlyssning av anrop till minimala API-Mappa metoder med statiskt genererade varianter vid körning. Användningen av interceptorer resulterar i ökad startprestanda för appar som kompilerats med PublishAot
.
Loggning och undantagshantering i kompileringsgenererade minimala API:er
Minimala API:er som genereras vid körning stöder automatiskt loggning (eller utlöser undantag i utvecklingsmiljöer) när parameterbindningen misslyckas. .NET 8 introducerar samma stöd för API:er som genererades vid kompileringstillfället via Request Delegate Generator (RDG). Mer information finns i Loggning och undantagshantering i kompileringstid genererade minimala API:er.
AOT och System.Text.Json
Minimala API:er är optimerade för att ta emot och returnera JSON-nyttolaster med hjälp av System.Text.Json
, så kompatibilitetskraven för JSON och intern AOT gäller också. Intern AOT-kompatibilitet kräver användning av System.Text.Json
-källgeneratorn. Alla typer som accepteras som parametrar till eller returneras från request-delegater i minimal-API:er måste konfigureras på en JsonSerializerContext
som är registrerad via ASP.NET Cores beroendeinjektion, till exempel:
// Register the JSON serializer context with DI
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});
...
// Add types used in the minimal API app to source generated JSON serializer content
[JsonSerializable(typeof(Todo[]))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{
}
Mer information om TypeInfoResolverChain API finns i följande resurser:
- JsonSerializerOptions.TypeInfoResolverChain
- kedjekällgeneratorer
- ändringar som stöder källgenerering
Bibliotek och intern AOT
Många av de vanliga biblioteken som är tillgängliga för ASP.NET Core-projekt har i dag vissa kompatibilitetsproblem om de används i ett projekt som är inriktat på intern AOT. Populära bibliotek förlitar sig ofta på de dynamiska funktionerna i .NET-reflektion för att inspektera och identifiera typer, villkorligt läsa in bibliotek vid körning och generera kod i farten för att implementera deras funktioner. Dessa bibliotek måste uppdateras för att kunna användas med Native AOT genom att använda verktyg som Roslyn-källgeneratorer.
Biblioteksförfattare som vill lära sig mer om att förbereda sina bibliotek för native AOT uppmuntras att börja med att att förbereda sitt bibliotek för att trimma och lära sig mer om interna AOT-kompatibilitetskrav.
Kestrel- och HTTP.sys-servrar
Det finns flera nya funktioner för Kestrel och HTTP.sys.
Stöd för namngivna rör i Kestrel
Namngivna rör är en populär teknik för att bygga kommunikation mellan processer, även kallat IPC, mellan Windows-program. Nu kan du skapa en IPC-server med hjälp av .NET, Kestreloch namngivna pipes.
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenNamedPipe("MyPipeName");
});
Mer information om den här funktionen och hur du använder .NET och gRPC för att skapa en IPC-server och -klient finns i kommunikation mellan processer med gRPC-.
Prestandaförbättringar för namngivna rörtransport
Vi har förbättrat prestanda för namngivna röranslutningar. Kestrel:s namngivna rörkommunikation accepterar nu anslutningar parallellt och återanvänder instanser av NamedPipeServerStream.
Dags att skapa 100 000 anslutningar:
- Före : 5,916 sekunder
- Efter : 2,374 sekunder
HTTP/2 via TLS -stöd (HTTPS) på macOS i Kestrel
.NET 8 lägger till stöd för Application-Layer Protocol Negotiation (ALPN) till macOS. ALPN är en TLS-funktion som används för att förhandla om vilket HTTP-protokoll en anslutning ska använda. ALPN tillåter till exempel webbläsare och andra HTTP-klienter att begära en HTTP/2-anslutning. Den här funktionen är särskilt användbar för gRPC-appar som kräver HTTP/2. Mer information finns i Använda HTTP/2 med webbservern ASP.NET Core Kestrel.
Övervakning av certifikatfil i Kestrel
TLS-certifikat konfigurerade med sökväg övervakas nu för ändringar när reloadOnChange
skickas till KestrelServerOptions.Configure(). En ändring av certifikatfilen behandlas på samma sätt som en ändring av den konfigurerade sökvägen (d.s. slutpunkter läses in igen).
Observera att filborttagningar specifikt inte spåras eftersom de uppstår tillfälligt och skulle krascha servern om de inte är tillfälliga.
Varning när angivna HTTP-protokoll inte används
Om TLS är inaktiverat och HTTP/1.x är tillgängligt inaktiveras HTTP/2 och HTTP/3, även om de har angetts. Detta kan orsaka några otäcka överraskningar, så vi har lagt till varningsutdata för att meddela dig när det händer.
HTTP_PORTS
och HTTPS_PORTS
konfigurationsnycklar
Program och containrar får ofta bara en port att lyssna på, till exempel 80, utan ytterligare begränsningar som värd eller sökväg.
HTTP_PORTS
och HTTPS_PORTS
är nya konfigurationsnycklar som gör det möjligt att ange lyssningsportarna för Kestrel- och HTTP.sys-servrarna. Dessa kan definieras med DOTNET_
eller ASPNETCORE_
miljövariabelprefix, eller anges direkt via andra konfigurationsindata som appsettings.json. Var och en är en semikolonavgränsad lista med portvärden. Till exempel:
ASPNETCORE_HTTP_PORTS=80;8080
ASPNETCORE_HTTPS_PORTS=443;8081
Detta är en förkortning för följande, som anger schemat (HTTP eller HTTPS) och valfri värd eller IP:en:
ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
Mer information finns i Konfigurera slutpunkter för ASP.NET Core Kestrel-webbservern och HTTP.sys webbserverimplementering i ASP.NET Core.
SNI-värdnamn i ITlsHandshakeFeature
Värdnamnet för servernamnindikeringen (SNI) visas nu i egenskapen HostName för ITlsHandshakeFeature-gränssnittet.
SNI är en del av TLS-handskakningsprocessen. Det gör att klienter kan ange det värdnamn som de försöker ansluta till när servern är värd för flera virtuella värdar eller domäner. För att kunna presentera rätt säkerhetscertifikat under handskakningsprocessen måste servern känna till det värdnamn som valts för varje begäran.
Normalt hanteras värdnamnet endast i TLS-stacken och används för att välja det matchande certifikatet. Men genom att exponera den kan andra komponenter i en app använda den informationen för ändamål som diagnostik, hastighetsbegränsning, routning och fakturering.
Att exponera värdnamnet är användbart för storskaliga tjänster som hanterar tusentals SNI-bindningar. Den här funktionen kan avsevärt förbättra effektiviteten i felsökning vid kunders eskaleringar. Den ökade transparensen möjliggör snabbare problemlösning och förbättrad tillförlitlighet för tjänsten.
Mer information finns i ITlsHandshakeFeature.HostName.
IHttpSysRequestTimingFeature
[IHttpSysRequestTimingFeature](https://source.dot.net/#Microsoft.AspNetCore.Server.HttpSys/IHttpSysRequestTimingFeature.cs,3c5dc86dc837b1f4) innehåller detaljerad tidsinformation för begäranden när du använder [HTTP.sys-servern](xref:fundamentals/servers/httpsys) och [In-process hosting med IIS](xref:host-and-deploy/iis/in-process-hosting?view=aspnetcore-8.0&preserve-view=true#ihsrtf8):- Tidsstämplar hämtas med hjälp av QueryPerformanceCounter.
- Frekvensen för tidsstämpeln kan erhållas via QueryPerformanceFrequency.
- Indexet för tidsinställningen kan skickas till HttpSysRequestTimingType för att veta vad tidpunkten representerar.
- Värdet kan vara 0 om tidpunkten inte är tillgänglig för den aktuella begäran.
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseHttpSys();
var app = builder.Build();
app.Use((context, next) =>
{
var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger("Sample");
var timingType = HttpSysRequestTimingType.RequestRoutingEnd;
if (feature.TryGetTimestamp(timingType, out var timestamp))
{
logger.LogInformation("Timestamp {timingType}: {timestamp}",
timingType, timestamp);
}
else
{
logger.LogInformation("Timestamp {timingType}: not available for the "
+ "current request", timingType);
}
return next(context);
});
app.MapGet("/", () => Results.Ok());
app.Run();
Mer information finns i Hämta detaljerad tidsinformation med IHttpSysRequestTimingFeature och Tidsinformation och In-process hosting med IIS.
HTTP.sys: tillvalsstöd för svarsbuffring i kernelläge
I vissa scenarier kan stora mängder små skrivningar med hög svarstid orsaka betydande prestandapåverkan för HTTP.sys
. Den här effekten beror på att det inte finns någon Pipe buffert i HTTP.sys
implementeringen. För att förbättra prestanda i dessa scenarier har stöd för svarsbuffertning lagts till i HTTP.sys
. Aktivera buffring genom att ställa in HttpSysOptions.EnableKernelResponseBuffering till true
.
Svarsbuffertning ska aktiveras av en app som utför synkron I/O eller asynkron I/O med högst en utestående skrivning i taget. I dessa scenarier kan svarsbuffertning avsevärt förbättra dataflödet över anslutningar med långa svarstider.
Appar som använder asynkron I/O och som kan ha fler än en skrivbehörighet åt gången bör inte använda den här flaggan. Om du aktiverar den här flaggan kan det leda till högre processor- och minnesanvändning av HTTP.Sys.
Autentisering och auktorisering
ASP.NET Core 8 lägger till nya funktioner för autentisering och auktorisering.
Identity API-slutpunkter
MapIdentityApi<TUser>
är en ny tilläggsmetod som lägger till två API-slutpunkter (/register
och /login
). Huvudmålet med MapIdentityApi
är att göra det enkelt för utvecklare att använda ASP.NET Core Identity för autentisering i JavaScript-baserade ensidesappar (SPA) eller Blazor-appar. I stället för att använda standardgränssnittet som tillhandahålls av ASP.NET Core Identity, som baseras på Razor Pages, lägger MapIdentityApi till JSON API-slutpunkter som är mer anpassade för SPA-appar och icke-webbläsarappar. Mer information finns i Identity API-slutpunkter.
IAuthorizationRequirementData
Innan ASP.NET Core 8 lägger du till en parameteriserad auktoriseringsprincip till en slutpunkt som krävs för att implementera en:
-
AuthorizeAttribute
för varje policy. -
AuthorizationPolicyProvider
för att bearbeta en anpassad princip från ett strängbaserat kontrakt. -
AuthorizationRequirement
för policyn. -
AuthorizationHandler
för varje krav.
Tänk dig till exempel följande exempel som skrivits för ASP.NET Core 7.0:
using AuthRequirementsData.Authorization;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddControllers();
builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
var app = builder.Build();
app.MapControllers();
app.Run();
using Microsoft.AspNetCore.Mvc;
namespace AuthRequirementsData.Controllers;
[ApiController]
[Route("api/[controller]")]
public class GreetingsController : Controller
{
[MinimumAgeAuthorize(16)]
[HttpGet("hello")]
public string Hello() => $"Hello {(HttpContext.User.Identity?.Name ?? "world")}!";
}
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;
namespace AuthRequirementsData.Authorization;
class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
{
private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;
public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
{
_logger = logger;
}
// Check whether a given MinimumAgeRequirement is satisfied or not for a particular
// context.
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
MinimumAgeRequirement requirement)
{
// Log as a warning so that it's very clear in sample output which authorization
// policies(and requirements/handlers) are in use.
_logger.LogWarning("Evaluating authorization requirement for age >= {age}",
requirement.Age);
// Check the user's age
var dateOfBirthClaim = context.User.FindFirst(c => c.Type ==
ClaimTypes.DateOfBirth);
if (dateOfBirthClaim != null)
{
// If the user has a date of birth claim, check their age
var dateOfBirth = Convert.ToDateTime(dateOfBirthClaim.Value, CultureInfo.InvariantCulture);
var age = DateTime.Now.Year - dateOfBirth.Year;
if (dateOfBirth > DateTime.Now.AddYears(-age))
{
// Adjust age if the user hasn't had a birthday yet this year.
age--;
}
// If the user meets the age criterion, mark the authorization requirement
// succeeded.
if (age >= requirement.Age)
{
_logger.LogInformation("Minimum age authorization requirement {age} satisfied",
requirement.Age);
context.Succeed(requirement);
}
else
{
_logger.LogInformation("Current user's DateOfBirth claim ({dateOfBirth})" +
" does not satisfy the minimum age authorization requirement {age}",
dateOfBirthClaim.Value,
requirement.Age);
}
}
else
{
_logger.LogInformation("No DateOfBirth claim present");
}
return Task.CompletedTask;
}
}
Det fullständiga exemplet är här i AspNetCore.Docs.Samples-lagringsplatsen.
ASP.NET Core 8 introducerar IAuthorizationRequirementData-gränssnittet. Med IAuthorizationRequirementData
-gränssnittet kan attributdefinitionen ange de krav som är associerade med auktoriseringsprincipen. Med hjälp av IAuthorizationRequirementData
kan den föregående policykoden för anpassad auktorisering skrivas med färre kodrader. Den uppdaterade Program.cs
filen:
using AuthRequirementsData.Authorization;
using Microsoft.AspNetCore.Authorization;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddControllers();
- builder.Services.AddSingleton<IAuthorizationPolicyProvider, MinimumAgePolicyProvider>();
builder.Services.AddSingleton<IAuthorizationHandler, MinimumAgeAuthorizationHandler>();
var app = builder.Build();
app.MapControllers();
app.Run();
Den uppdaterade MinimumAgeAuthorizationHandler
:
using Microsoft.AspNetCore.Authorization;
using System.Globalization;
using System.Security.Claims;
namespace AuthRequirementsData.Authorization;
- class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeRequirement>
+ class MinimumAgeAuthorizationHandler : AuthorizationHandler<MinimumAgeAuthorizeAttribute>
{
private readonly ILogger<MinimumAgeAuthorizationHandler> _logger;
public MinimumAgeAuthorizationHandler(ILogger<MinimumAgeAuthorizationHandler> logger)
{
_logger = logger;
}
// Check whether a given MinimumAgeRequirement is satisfied or not for a particular
// context
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
- MinimumAgeRequirement requirement)
+ MinimumAgeAuthorizeAttribute requirement)
{
// Remaining code omitted for brevity.
Det fullständiga uppdaterade exemplet finns här.
Se Anpassade auktoriseringsprinciper med IAuthorizationRequirementData för en detaljerad undersökning av det nya exemplet.
Skydda Swagger UI-slutpunkter
Swagger UI-slutpunkter kan nu skyddas i produktionsmiljöer genom att anropa MapSwagger().RequireAuthorization
. Mer information finns i Skydda Swagger UI-slutpunkter
Diverse
I följande avsnitt beskrivs olika nya funktioner i ASP.NET Core 8.
Stöd för nyckelade tjänster i beroendeinmatning
keyed services refererar till en mekanism för att registrera och hämta DI-tjänster (Dependency Injection) med hjälp av nycklar. En tjänst associeras med en nyckel genom att anropa AddKeyedSingleton (eller AddKeyedScoped
eller AddKeyedTransient
) för att registrera den. Få åtkomst till en registrerad tjänst genom att ange nyckeln med attributet [FromKeyedServices]
. Följande kod visar hur du använder nyckelade tjänster:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKeyedSingleton<ICache, BigCache>("big");
builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");
builder.Services.AddControllers();
var app = builder.Build();
app.MapGet("/big", ([FromKeyedServices("big")] ICache bigCache) => bigCache.Get("date"));
app.MapGet("/small", ([FromKeyedServices("small")] ICache smallCache) =>
smallCache.Get("date"));
app.MapControllers();
app.Run();
public interface ICache
{
object Get(string key);
}
public class BigCache : ICache
{
public object Get(string key) => $"Resolving {key} from big cache.";
}
public class SmallCache : ICache
{
public object Get(string key) => $"Resolving {key} from small cache.";
}
[ApiController]
[Route("/cache")]
public class CustomServicesApiController : Controller
{
[HttpGet("big-cache")]
public ActionResult<object> GetOk([FromKeyedServices("big")] ICache cache)
{
return cache.Get("data-mvc");
}
}
public class MyHub : Hub
{
public void Method([FromKeyedServices("small")] ICache cache)
{
Console.WriteLine(cache.Get("signalr"));
}
}
Visual Studio-projektmallar för SPA-appar med ASP.NET Core-serverdel
Visual Studio-projektmallar är nu det rekommenderade sättet att skapa single-page-appar (SPAs eller ensidesapplikationer) som har en ASP.NET Core-serverdel. Mallar tillhandahålls som skapar appar baserat på JavaScript-ramverken Angular, Reactoch Vue. Följande mallar:
- Skapa en Visual Studio-lösning med ett klientdelsprojekt och ett serverdelsprojekt.
- Använd Visual Studio-projekttypen för JavaScript och TypeScript (.esproj) för klientdelen.
- Använd ett ASP.NET Core-projekt för serverdelen.
Mer information om Visual Studio-mallar och hur du får åtkomst till äldre mallar finns i Översikt över ensidesappar (SPA) i ASP.NET Core
Stöd för generiska attribut
Attribut som tidigare krävde en Type-parameter är nu tillgängliga i renare generiska varianter. Detta möjliggörs av stöd för generiska attribut i C# 11. Syntaxen för att kommentera svarstypen för en åtgärd kan till exempel ändras på följande sätt:
[ApiController]
[Route("api/[controller]")]
public class TodosController : Controller
{
[HttpGet("/")]
- [ProducesResponseType(typeof(Todo), StatusCodes.Status200OK)]
+ [ProducesResponseType<Todo>(StatusCodes.Status200OK)]
public Todo Get() => new Todo(1, "Write a sample", DateTime.Now, false);
}
Allmänna varianter stöds för följande attribut:
[ProducesResponseType<T>]
[Produces<T>]
[MiddlewareFilter<T>]
[ModelBinder<T>]
[ModelMetadataType<T>]
[ServiceFilter<T>]
[TypeFilter<T>]
Kodanalys i ASP.NET Core-appar
De nya analysverktygen som visas i följande tabell är tillgängliga i ASP.NET Core 8.0.
Diagnostik-ID | Brytande eller icke-brytande | Beskrivning |
---|---|---|
ASP0016 | Oskiljbar | Returnera inte ett värde från RequestDelegate |
ASP0019 | Oskiljbar | Det föreslås att du använder IHeaderDictionary.Append eller indexeraren |
ASP0020 | Oskiljbar | Komplexa typer som refereras till av vägparametrar måste vara parsbara |
ASP0021 | Oskiljbar | Returtypen för BindAsync-metoden måste vara ValueTask<T> |
ASP0022 | Oskiljbar | Routningskonflikt identifierad mellan routningshanterare |
ASP0023 | Oskiljbar | MVC: Routningskonflikten har identifierats mellan routningshanterare |
ASP0024 | Oskiljbar | Routningshanteraren har flera parametrar med attributet [FromBody] |
ASP0025 | Oskiljbar | Använd AddAuthorizationBuilder |
Routningsverktyg
ASP.NET Core bygger på routning. Minimala API:er, webb-API:er, Razor-sidor och Blazor använder alla rutter för att anpassa hur HTTP-begäranden mappas till kod.
I .NET 8 har vi investerat i en uppsättning nya funktioner för att göra routning enklare att lära sig och använda. Dessa nya funktioner är:
- Vägsyntax som markerar
- Komplettera automatiskt med parameter- och routningsnamn
- Komplettera routningsbegränsningar automatiskt
- Route-analysverktyg och korrigeringar
- stöd för minimala API:er, webb-API:er och Blazor
Mer information finns i Route-verktyg i .NET 8.
ASP.NET Core-metrik
Mått är mått som rapporteras över tid och används oftast för att övervaka hälsotillståndet för en app och för att generera aviseringar. En räknare som rapporterar misslyckade HTTP-begäranden kan till exempel visas i instrumentpaneler eller generera aviseringar när fel passerar ett tröskelvärde.
Den här förhandsversionen lägger till nya mått i ASP.NET Core med hjälp av System.Diagnostics.Metrics.
Metrics
är ett modernt API för rapportering och insamling av information om appar.
Metrik erbjuder många förbättringar jämfört med befintliga händelseräknare.
- Nya typer av mätningar med räknare, mätare och histogram.
- Kraftfull rapportering med flerdimensionella värden.
- Integrering i det bredare molnbaserade ekosystemet genom att anpassa till OpenTelemetry-standarder.
Mätvärden har lagts till för värd för ASP.NET Core, Kestreloch SignalR. Mer information finns i System.Diagnostics.Metrics.
IExceptionHandler
IExceptionHandler är ett nytt gränssnitt som ger utvecklaren ett återanrop för hantering av kända undantag på en central plats.
IExceptionHandler
implementeringar registreras genom att anropa IServiceCollection.AddExceptionHandler<T>
. Flera implementeringar kan läggas till och de anropas i den registrerade ordningen. Om en undantagshanterare hanterar en begäran kan den returnera true
för att stoppa bearbetningen. Om ett undantag inte hanteras av någon undantagshanterare återgår kontrollen till standardbeteendet och alternativen från mellanprogrammet.
Mer information finns i IExceptionHandler.
Förbättrad felsökningsupplevelse
Anpassningsattribut för felsökning har lagts till i typer som HttpContext
, HttpRequest
, HttpResponse
, ClaimsPrincipal
och WebApplication
. Det förbättrade felsökningsverktyget för dessa typer gör det enklare att hitta viktig information i en IDE:s felsökare. Följande skärmbilder visar skillnaden som dessa attribut gör i felsökningsprogrammets visning av HttpContext
.
.NET 7:
.NET 8:
Felsökningsvisningen för WebApplication
visar viktig information, till exempel konfigurerade slutpunkter, mellanprogram och IConfiguration
värden.
.NET 7:
.NET 8:
Mer information om felsökning av förbättringar i .NET 8 finns i:
- Felsökningsförbättringar I .NET 8
- GitHub-problem dotnet/aspnetcore 48205
IPNetwork.Parse
och TryParse
De nya metoderna Parse och TryParse på IPNetwork lägger till stöd för att skapa en IPNetwork
med hjälp av en indatasträng i CIDR-notation eller "snedstrecksnotation".
Här är IPv4-exempel:
// Using Parse
var network = IPNetwork.Parse("192.168.0.1/32");
// Using TryParse
bool success = IPNetwork.TryParse("192.168.0.1/32", out var network);
// Constructor equivalent
var network = new IPNetwork(IPAddress.Parse("192.168.0.1"), 32);
Och här är exempel på IPv6:
// Using Parse
var network = IPNetwork.Parse("2001:db8:3c4d::1/128");
// Using TryParse
bool success = IPNetwork.TryParse("2001:db8:3c4d::1/128", out var network);
// Constructor equivalent
var network = new IPNetwork(IPAddress.Parse("2001:db8:3c4d::1"), 128);
Redis-baserad cachelagring av utdata
ASP.NET Core 8 lägger till stöd för att använda Redis som en distribuerad cache för cachelagring av utdata. Cachelagring av utdata är en funktion som gör det möjligt för en app att cachelagra utdata från en minimal API-slutpunkt, kontrollantåtgärd eller Razor sida. Mer information finns i cachelagring av utdata.
Kortslutningsmellanprogram efter routning
När routningen matchar en slutpunkt låter den vanligtvis resten av pipelinen för mellanprogram köras innan slutpunktslogik anropas. Tjänster kan minska resursanvändningen genom att filtrera bort kända begäranden tidigt i pipelinen. Använd ShortCircuit-tilläggsmetoden för att få routning att anropa slutpunktslogik omedelbart och sedan avsluta begäran. En viss väg kanske till exempel inte behöver gå igenom autentisering eller CORS-mellanprogram. Följande exempel avbryter förfrågningar som matchar den /short-circuit
rutten.
app.MapGet("/short-circuit", () => "Short circuiting!").ShortCircuit();
Använd metoden MapShortCircuit för att konfigurera genvägar för flera rutter samtidigt genom att skicka en parameterlista med URL-prefix till den. Webbläsare och robotar avsöker till exempel ofta servrar efter välkända sökvägar som robots.txt
och favicon.ico
. Om appen inte har dessa filer kan en kodrad konfigurera båda vägarna:
app.MapShortCircuit(404, "robots.txt", "favicon.ico");
Mer information finns i kortslutningsmellanlager efter routning.
Utökningsbarhet för HTTP-loggning av mellanprogram
HTTP-loggningsmellanprogrammet har flera nya funktioner:
- HttpLoggingFields.Duration: När det är aktiverat genererar mellanprogrammet en ny logg i slutet av begäran och svaret som mäter den totala tid som tagits för bearbetning. Detta nya fält har lagts till i denna HttpLoggingFields.All uppsättning.
- HttpLoggingOptions.CombineLogs: När det är aktiverat konsoliderar mellanprogrammet alla sina aktiverade loggar för en begäran och ett svar i en logg i slutet. Ett enda loggmeddelande innehåller begäran, begärandetext, svar, svarstext och varaktighet.
-
IHttpLoggingInterceptor: Ett nytt gränssnitt för en tjänst som kan implementeras och registreras (med AddHttpLoggingInterceptor) för att ta emot återanrop per begäran och per svar för att anpassa vilken information som loggas. Alla slutpunktsspecifika logginställningar tillämpas först och kan sedan åsidosättas i dessa återanrop. En implementering kan:
- Granska en begäran och ett svar.
- Aktivera eller inaktivera alla HttpLoggingFields.
- Justera hur mycket av begärande- eller svarstexten som loggas.
- Lägg till anpassade fält i loggarna.
Mer information finns i HTTP-loggning i .NET Core och ASP.NET Core.
Nya API:er i ProblemDetails för att stödja mer motståndskraftiga integreringar
I .NET 7 introducerades tjänsten ProblemDetails för att förbättra upplevelsen för att generera felsvar som uppfyller ProblemDetails-specifikationen. I .NET 8 har ett nytt API lagts till för att göra det enklare att implementera återställningsbeteende om IProblemDetailsService inte kan generera ProblemDetails. I följande exempel visas användningen av det nya TryWriteAsync-API:et:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
var app = builder.Build();
app.UseExceptionHandler(exceptionHandlerApp =>
{
exceptionHandlerApp.Run(async httpContext =>
{
var pds = httpContext.RequestServices.GetService<IProblemDetailsService>();
if (pds == null
|| !await pds.TryWriteAsync(new() { HttpContext = httpContext }))
{
// Fallback behavior
await httpContext.Response.WriteAsync("Fallback: An error occurred.");
}
});
});
app.MapGet("/exception", () =>
{
throw new InvalidOperationException("Sample Exception");
});
app.MapGet("/", () => "Test by calling /exception");
app.Run();
För mer information, se IProblemDetailsService-reservlösning
Ytterligare resurser
ASP.NET Core