Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel werden die wichtigsten Änderungen der ASP.NET Core in .NET 11 mit Links zu relevanter Dokumentation hervorgehoben.
Dieser Artikel wird aktualisiert, wenn neue Vorschauversionen verfügbar gemacht werden.
Blazor
In diesem Abschnitt werden neue Features für Blazorbeschrieben.
Neue DisplayName Komponente und Unterstützung für [Display] und [DisplayName] Attribute
Die DisplayName Komponente kann verwendet werden, um Eigenschaftennamen aus Metadatenattributen anzuzeigen:
[Required, DisplayName("Production Date")]
public DateTime ProductionDate { get; set; }
Das [Display] Attribut für die Modellklasseneigenschaft wird unterstützt:
[Required, Display(Name = "Production Date")]
public DateTime ProductionDate { get; set; }
Von den beiden Ansätzen wird das [Display] Attribut empfohlen, wodurch zusätzliche Eigenschaften zur Verfügung gestellt werden. Das [Display] Attribut ermöglicht auch das Zuweisen eines Ressourcentyps für die Lokalisierung. Wenn beide Attribute vorhanden sind, hat [Display] Vorrang vor [DisplayName]. Wenn kein Attribut vorhanden ist, greift die Komponente auf den Eigenschaftennamen zurück.
Verwenden Sie die DisplayName Komponente in Beschriftungen oder Tabellenüberschriften:
<label>
<DisplayName For="@(() => Model!.ProductionDate)" />
<InputDate @bind-Value="Model!.ProductionDate" />
</label>
Blazor Webskript-Startoptionenformat jetzt unterstützt für Blazor Server und Blazor WebAssembly Skripts
Das Blazor Web App Script (blazor.web.js)-Optionsobjekt, das an Blazor.start() übergeben wird, verwendet das folgende Format seit der Veröffentlichung von .NET 8:
Blazor.start({
ssr: { ... },
circuit: { ... },
webAssembly: { ... },
});
Blazor Server Jetzt können (blazor.server.js) und Blazor WebAssembly (blazor.webassembly.js) Skripts dasselbe Optionsformat verwenden.
Das folgende Beispiel zeigt das format der vorherigen Optionen, das weiterhin unterstützt wird:
Blazor.start({
loadBootResource: function (...) {
...
},
});
Das neu unterstützte Optionsformat für das vorherige Beispiel:
Blazor.start({
webAssembly: {
loadBootResource: function (...) {
...
},
},
});
Weitere Informationen finden Sie unter ASP.NET Core Blazor startup.
Neue BasePath-Komponente
Blazor Web Apps können die neue Komponente BasePath (<BasePath />) verwenden, um den Basispfad der App (<base href>) automatisch als HTML-Tag darzustellen. Weitere Informationen finden Sie unter ASP.NET Core Blazor App-Basispfad.
Inline-Ereignishandler JS aus der NavMenu Komponente entfernt
Der Inline-Ereignishandler JS, der die Anzeige von Navigationslinks umschaltet, ist in der Komponente NavMenu der Projektvorlage Blazor Web App nicht mehr vorhanden. Apps, die aus der Projektvorlage generiert wurden, verwenden jetzt einen verbundbasierten JS Modulansatz , um die Navigationsleiste auf der gerenderten Seite ein- oder auszublenden. Der neue Ansatz verbessert die Compliance von Inhaltssicherheitsrichtlinien (Content Security Policy, CSP), da der CSP keinen unsicheren Hash für die Inline JSenthält.
Informationen zum Migrieren einer vorhandenen App zu .NET 11, einschließlich der Übernahme des neuen JS Modulansatzes für den Navigationsleisten-Toggler, finden Sie unter Migrate von ASP.NET Core in .NET 10 bis ASP.NET Core in .NET 11.
NavigateTo und NavLink Support für relative Navigation
Der neue RelativeToCurrentUri Parameter (Standard: false) für NavigationManager.NavigateTo und die NavLink Komponente ermöglicht es Ihnen, zu URIs relativ zum aktuellen Seitenpfad zu navigieren, anstatt zum Basis-URI der App.
Betrachten Sie die folgenden geschachtelten Endpunkte:
/docs/getting-started/installation/configuration
Wenn die URI des Browsers /docs/getting-started/installation lautet und Sie den Benutzer zu /docs/getting-started/configuration navigieren möchten, leitet NavigateTo("/configuration") stattdessen zu /configuration im Stammverzeichnis der Anwendung um, anstatt zum relativen Pfad unter /docs/getting-started/configuration. Legen Sie das RelativeToCurrentUri mit NavigateTo oder die NavLink Komponente für die gewünschte Navigation fest:
Navigation.NavigateTo("/configuration", new NavigationOptions
{
RelativeToCurrentUri = true
});
<NavLink href="configuration" RelativeToCurrentUri="true">Configuration</NavLink>
Beibehaltung temporärer Daten zwischen HTTP-Anfragen beim statischen serverseitigen Rendering (Static SSR)
Um temporäre Daten zwischen HTTP-Anforderungen während des statischen serverseitigen Renderings (static SSR) zu sichern, unterstützt Blazor TempData. TempData eignet sich ideal für Szenarien wie Flashnachrichten nach Formularübermittlungen, Übergeben von Daten während umleitungen (POST-Redirect-GET Muster) und einmalige Benachrichtigungen.
TempData ist verfügbar, wenn AddRazorComponents in der App-Datei Program aufgerufen wird und als kaskadierender Wert mit dem [CascadingParameter] Attribut bereitgestellt wird.
[CascadingParameter]
public ITempData? TempData { get; set; }
Verwenden Sie beim Angeben eines Parameters für einfaches Lesen/Schreiben eines einzelnen Werts das [SupplyParameterFromTempData] Attribut:
[SupplyParameterFromTempData]
public string? Message { get; set; }
Weitere Informationen finden Sie unter ASP.NET Core Blazor serverseitige Zustandsverwaltung.
Neue Blazor Web Worker-Vorlage (blazorwebworker)
Die .NET Web Worker-Projektvorlage, die einen Web Worker-Client zum Auslagern langer Arbeit in einen Hintergrundthread enthält, wurde in die Projektvorlage Blazor Web Worker Projektvorlage (blazorwebworker) umbenannt. Die Namensänderung macht deutlicher, dass die Vorlage Teil des Stapels für die Blazor Verwendung in Blazor WebAssembly und Blazor Web-Apps (für clientseitiges Rendering, CSR) ist.
Dem generierten WebWorkerClient wurden zwei häufig nachgefragte Funktionen hinzugefügt:
-
InvokeVoidAsyncfür Fire-and-Forget-Worker-Aufrufe, die keinen Wert zurückgeben und analog zuIJSRuntimeaufgebaut sind. - Unterstützung für Abbruch und Timeouts sowohl bei der Worker-Erstellung als auch bei Worker-Aufrufen, sodass Aufrufer ein
CancellationTokenübergeben und einen hängengebliebenen Worker sauber beenden können.
Vorhandene Projekte, die mit der alten Vorlage erstellt wurden, funktionieren weiterhin. Die Umbenennung betrifft nur den Vorlagennamen, der in dotnet new list und in der Liste der Vorlagen Neues Projekt erstellen von Visual Studio angezeigt wird.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- ASP.NET Core Blazor mit .NET für Web Worker
-
Aktualisierung der .NET Web Worker-Vorlage auf die Blazor Web Worker-Vorlage (
dotnet/aspnetcore#66070) (Bitte kommentieren Sie keine geschlossenen Issues und PRs.)
Virtualisierungsverbesserungen
Die Virtualize<TItem> Komponente geht nicht mehr davon aus, dass jedes Element dieselbe Höhe hat. Zuvor deaktivierte die Komponente die native Scroll-Verankerung des Browsers (um eine endlose Rendering-Schleife zu vermeiden), was bedeutete, dass jede Höhenänderung oberhalb des Viewports – etwa durch das Erweitern von Elementen, Datenaktualisierungen oder verzögert geladene Inhalte – sichtbare Elemente auf dem Bildschirm springen ließ. Die
VirtualizeKomponente passt sich jetzt zur Laufzeit an die gemessenen Elementgrößen an, wodurch fehlerhafte Abstände und fehlerhaftes Scrollverhalten reduziert werden, wenn die Elementhöhen variieren.Die Updates verwenden einen hybriden Ansatz: native CSS-Scroll-Verankerung in Browsern, die diese für Layouts ohne
<table>unterstützen, mit einem manuellen, aufResizeObserverbasierenden Fallback zur Scroll-Kompensation für<table>-Layouts und Safari, da die native Verankerung bei<tr>-Elementen Positionen falsch berechnet.Apps, die die
VirtualizeKomponente verwenden, erhalten automatisch die Vorteile dieser Updates. Es sind keine Entwickler-API-Änderungen erforderlich.Zu diesen Updates gehört eine Aktualisierung des Standardwerts Virtualize<TItem>.OverscanCount, die in .NET 10 oder höher
3wurde und jetzt in15in .NET 11 oder höher geändert wurde. Die Änderung des Standardwerts erhöht die Genauigkeit der Berechnung der durchschnittlichen Elementhöhe.Weitere Informationen finden Sie in den folgenden Ressourcen:
- Abschnitt „Elementgröße“ und Abschnitt „Overscan-Anzahl“ des Artikels „Virtualisierung“.
-
[Virtualisierung] Sichtbarer Inhalt verschiebt sich nicht, wenn sich die Höhe von im DOM befindlichen Elementen oberhalb des Viewports ändert (
dotnet/aspnetcore#65951) (Bitte kommentieren Sie keine geschlossenen Issues und PRs).
Verwenden Sie den neuen
AnchorModeParameter, um zu steuern, wie sich der Viewport an Listenrändern verhält, wenn Elemente dynamisch hinzugefügt werden:-
None: Keine Kantenheftung. Der Viewport bleibt unabhängig von Elementänderungen an der aktuellen Bildlaufposition. -
Beginning: Heftet den Viewport an den Anfang der Liste an. Zum Beispiel ist dieses Anheften für das Nutzungserlebnis in einem Newsfeed nützlich. -
End: Fixiert den Viewport am Ende der Liste. Zum Beispiel ist dieses Anheftungsverhalten nützlich für eine Chat- oder Protokollierungs-Benutzererfahrung.
Im folgenden Beispiel wird der virtualisierte Inhalt an den Anfang der Liste angeheftet:
<Virtualize AnchorMode="Beginning" ...> ... </Virtualize>Weitere Informationen finden Sie in den folgenden Ressourcen:
- ASP.NET Core Razor Component Virtualization
-
[release/11.0-preview4] Virtualization AnchorMode mit Unterstützung für variable Höhen (
dotnet/aspnetcore#66521) (Bitte kommentieren Sie keine geschlossenen Issues und PRs.)
-
Projektvorlage für neue Dienststandardbibliotheken für Blazor WebAssembly Apps
Die blazor-wasm-servicedefaults Projektvorlage erstellt eine Dienststandardbibliothek für Blazor WebAssembly Apps mit Aspire Integration. Weitere Informationen finden Sie unter Tooling for ASP.NET Core Blazor.
Neuer Entwicklungsserver für Blazor WebAssembly Apps
Microsoft.AspNetCore.Components.Gateway ist ein einfacher ASP.NET Core Host, der Microsoft.AspNetCore.Components.WebAssembly.DevServer ersetzt, um eigenständige Blazor WebAssembly-Apps während der Entwicklung und Produktion zu bedienen.
Um das Gateway in einer vorhandenen eigenständigen Blazor WebAssembly-App zu übernehmen, verweisen Sie in der Projektdatei der App auf das Vorschaupaket Microsoft.AspNetCore.Components.Gateway.
Note
Eine Anleitung zum Hinzufügen von Paketen zu .NET-Anwendungen finden Sie in den Artikeln unter Pakete installieren und verwalten unter Workflow für die Paketnutzung (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.
Benutzerdefinierter Routingcode und Middleware sind von der App nicht erforderlich. Fallback-Endpunkte stammen aus dem Manifest für statische Webressourcen, das vom SDK ausgegeben wird, wenn die Eigenschaft StaticWebAssetSpaFallbackEnabled in der Projektdatei der App festgelegt ist; diese ist standardmäßig in eigenständigen Blazor WebAssembly-Apps vorhanden, die aus der Projektvorlage erstellt werden:
<StaticWebAssetSpaFallbackEnabled>true</StaticWebAssetSpaFallbackEnabled>
Vor der Veröffentlichung von .NET 11 war die Eigenschaft inspectUri der Datei Properties/launchSettings.json:
- ermöglicht der IDE, zu ermitteln, ob es sich bei einer App um eine Blazor-App handelt.
- Weist die Skript-Debugging-Infrastruktur an, über den Debugging-Proxy von Blazor eine Verbindung zum Browser herzustellen.
Die Eigenschaft ist bei Verwendung des neuen Entwicklungsservers nicht mehr erforderlich.
Öffnen Sie die Properties/launchSettings.json-Datei des Startprojekts. Entfernen Sie die Eigenschaft inspectUri aus jedem Startprofil des Knotens profiles der Datei:
- "inspectUri": "..."
Weitere Informationen finden Sie unter [Blazor] Ersetzen von DevServer durch BlazorGateway für eigenständige WASM-Apps (dotnet/aspnetcore #65982) (Bitte kommentieren Sie keine geschlossenen Probleme und PRs).
Serverseitig ausgelöste Schaltkreispause
Dieses Feature gilt für serverseitige Blazor Apps.
Blazor unterstützt bereits das kontrollierte Pausieren und Fortsetzen von Circuits mit Blazor.pauseCircuit() und Blazor.resumeCircuit(). .NET 11 führt eine symmetrische serverseitige Pausen- und Fortsetzungsfunktion ein, bei der der Server anfordern kann, dass verbundene Clients den ordnungsgemäßen Schaltkreis-Pausenfluss starten.
Circuit.RequestCircuitPauseAsync(CancellationToken) wird verwendet, um anzufordern, dass der verbundene Client den ordnungsgemäßen Schaltkreis-Pausenfluss beginnt. Die CancellationToken Anforderung wird abgebrochen, bevor sie vom Framework akzeptiert wird. Die Methode gibt zurück true , wenn die Anforderung akzeptiert wurde und der Client aufgefordert wurde, mit dem Anhalten zu beginnen.
Dieses Feature ist in den folgenden Szenarien nützlich:
- Geplante Abschaltungen und Bereitstellungen.
- Instanzentwässerung.
- App-Wartungsfenster.
Weitere Informationen und ein Implementierungsbeispiel für Serverneustarts finden Sie unter ASP.NET Core Blazor serverseitige Zustandsverwaltung.
Kleinere Blazor WebAssembly Veröffentlichungsausgabe
Zwei Kürzungsänderungen verkleinern veröffentlichte Blazor WebAssembly-Apps, die nicht OpenTelemetry (OTEL) oder Hot Reload verwenden:
- Die Typen
ComponentsMetricsundComponentsActivitySourcesind jetzt an ein[FeatureSwitchDefinition]-Attribut gebunden, sodass der Trimmer die Metriken- und Tracing-Aufrufpfade ausRendererund verwandten Typen entfernen kann, wennSystem.Diagnostics.Metrics.Meter.IsSupportedauffalsefestgelegt ist (der Standardwert für getrimmte Apps) [browser][wasm] IL-Trimmen für OTEL implementieren (dotnet/aspnetcore#65901) (Bitte kommentieren Sie keine geschlossenen Issues und PRs). -
HotReloadManagerstellt nun eine per Feature-Schalter gesteuerte EigenschaftIsSupportedbereit, die anSystem.Reflection.Metadata.MetadataUpdater.IsSupportedgebunden ist, sodass der Trimmer bei der Veröffentlichung Hot-Reload-Caches und Registrierungen von Metadatenaktualisierungshandlern im gesamten Renderer entfernen kann [blazor][wasm] Hot-Reload-IL-Trimming beheben (dotnet/aspnetcore#65903) (Bitte kommentieren Sie keine geschlossenen Issues und PRs).
Apps, die OTEL oder Hot Reload verwenden, sind von den vorherigen Updates nicht betroffen.
QuickGrid Verbesserungen
Die komponente QuickGrid erhält mehrere neue Features in .NET 11.
Weitere Informationen zu den folgenden Features finden Sie unter ASP.NET Core Blazor Komponente "QuickGrid".
Paginierungsmodi
Vor der Veröffentlichung von .NET 11 wird der Paginierungs- und Sortierzustand im Arbeitsspeicher innerhalb der komponente QuickGrid verwaltet, ohne die URL zu ändern, die inner-state navigation genannt wird. Ein interaktiver Rendermodus ist erforderlich.
Mit der Veröffentlichung von .NET 11 unterstützt QuickGridURL-basierte Navigation.
Paginierung und Sortierzustand werden in der URL-Abfragezeichenfolge beibehalten. Wenn Benutzer paginieren oder sortieren, wird die URL aktualisiert (Beispiel: ?page=2&sort=Name&order=asc). Dies ermöglicht das Teilen von Links, die Browsernavigation mit Zurück/Vorwärts und statische SSR ohne Interaktionen.
Sortierbare Spaltenüberschriften und Paginatorsteuerelemente werden als <a> Elemente mit href Attributen gerendert. Die StaticHtmlRenderer rendert diese Anker. Bei jeder Anforderung liest der Server die Abfragezeichenfolge, um den aktuellen Seiten- und Sortierzustand zu ermitteln – keine JavaScript-Laufzeit erforderlich.
Abfragezeichenfolge-Parameter:
-
page: Eine 1-basierte Seitenzahl. Auf der ersten Seite wird der Parameter für saubere URLs weggelassen. -
sort: Spaltentitel zum Sortieren des Rasters. -
order: Aufsteigend (asc) oder absteigend (desc).
Die sort Spalte wird durch die Eigenschaft der Spalte Title identifiziert. Spalten ohne ein Title zeigen eine nicht anklickbare <div>-Kopfzeile an.
QuickGrid liest die URL bei der Initialisierung und abonniert NavigationManager.LocationChanged, sodass browser back/forward und direct URL entry funktionieren. Wenn Sortierparameter aus der URL entfernt werden, fällt sie auf die Standardsortierspalte/-richtung zurück.
Deaktivierte Paginator-Links verwenden aria-disabled="true" und pointer-events: none anstelle des HTML-Attributs disabled, das bei <a>-Elementen nicht existiert.
Mehrere Raster auf derselben Seite
Mehrere QuickGrid Komponenten auf derselben Seite erfordern eindeutige QueryParameterNamePrefix Werte, um Abfragezeichenfolgenkonflikte zu vermeiden. Das Standardpräfix ist eine leere Zeichenfolge, wodurch Parameter mit den Namen page, sort und order erzeugt werden. Das Festlegen des Präfixes auf "cities" erzeugt cities_page, , cities_sortund cities_order.
Jeder QuickGrid muss über eine eigene PaginationState Instanz verfügen. Mehrere Grids dürfen sich kein PaginationState teilen, wenn sie unterschiedliche Präfixe haben – das zuletzt gerenderte Grid überschreibt den Namen des Abfrageparameters im gemeinsam genutzten Zustand, wodurch Paginator aus dem falschen Parameter liest.
In Versionen vor .NET 11 funktionierten implizit die folgenden QuickGrid Komponenten:
<QuickGrid ... Pagination="@pagination1">
...
</QuickGrid>
<QuickGrid ... Pagination="@pagination2">
...
</QuickGrid>
Mit der Veröffentlichung von .NET 11 benötigen die folgenden QuickGrid-Komponenten eine eindeutige QueryParameterNamePrefix. Die erste QuickGrid verwendet das standardmäßige Präfix der leeren Zeichenfolge, während bei der zweiten cities als Präfix festgelegt wird:
<QuickGrid ... Pagination="@pagination1">
...
</QuickGrid>
<QuickGrid ... Pagination="@pagination2" QueryParameterNamePrefix="cities">
...
</QuickGrid>
Beispielabfragezeichenfolge für die vorherigen QuickGrid Komponenten:
?page=2&sort=Name&order=asc&cities_page=3&cities_sort=Country&cities_order=desc
Sortieren nach Spalten
Fügen Sie Sortable="true" zu einem PropertyColumn hinzu. Bei urlbasierter Navigation navigiert die Auswahl einer Kopfzeile zu einer URL mit aktualisierten sort Und order Parametern. Bei der Navigation innerhalb eines Zustands löst das Auswählen einer Kopfzeile @onclick aus, das SortByColumnAsync aufruft. In beiden Fällen SortByColumnAsync navigiert sie über NavigationManager.NavigateTo(GetSortQueryStringUrl(...)), sodass die URL immer den Sortierzustand widerspiegelt.
Titelbasierte Sortieridentifikation
Der Sortierzustand in der URL verwendet die Eigenschaft der Title Spalte als Bezeichner. Der Abfrageparameter sort ist auf column.Title festgelegt (Beispiel für den Spaltentitel Name: ?sort=Name&order=asc). Bei einer URL-Änderung ordnet QuickGrid den Wert sort durch Ausführen von _columns.FirstOrDefault(c => c.Title == sort.ColumnTitle) wieder einer Spalte zu. Wenn keine Spaltentitel übereinstimmen, wird die Sortierung ignoriert, und das Raster wird auf die Standardsortierung zurückfallen.
Das Umbenennen einer Spalte Title ist eine urlbrechende Änderung. Alle mit Lesezeichen versehenen oder geteilten URLs, die den alten Titel im Parameter sort enthalten, stimmen nicht mehr überein, und die Tabelle fällt stattdessen stillschweigend auf die Standardsortierung zurück, anstatt nach der beabsichtigten Spalte zu sortieren. Für PropertyColumn wird Title standardmäßig auf den Eigenschaftsnamen gesetzt (Beispiel: Property="@(p => p.FirstName)" führt zu Title="First Name"), sodass sowohl das Umbenennen der Eigenschaft als auch das explizite Ändern des Parameters Title vorhandene URLs ungültig machen.
Paginator
Paginatorinjiziert NavigationManager, abonniert LocationChanged und liest bei jeder Änderung der URL den Seitenindex aus dem Query-String.
GoToPageAsync navigiert zur Ziel-URL, anstatt PaginationState direkt zu verändern. Der Status wird über den LocationChanged Rückruffluss aktualisiert.
GetPageUrl gibt eine URL zurück, die die 1-basierte Seitenzahl enthält. Der Seitenindex 0 (Seite 1) lässt den Abfrageparameter vollständig aus.
Inkompatible CSS-Änderung
Wenn die URL-basierte Navigation aktiviert ist, müssen Selektoren, die auf button.col-title abzielen, auch auf a.col-title abzielen, und nav button/nav button:disabled erfordern nav a/nav a[aria-disabled="true"]. Das integrierte QuickGrid Stylesheet stellt standardmäßig beide bereit.
So deaktivieren Sie die URL-basierte Navigation
Um die URL-basierte Navigation zu deaktivieren, legen Sie den AppContext Schalter für das Feature auf :false
AppContext.SetSwitch(
"Microsoft.AspNetCore.Components.QuickGrid.EnableUrlBasedQuickGridNavigationAndSorting",
false);
Dies stellt <button>-Elemente mit @onclick-Handlern wieder her. Ein interaktiver Rendermodus ist erforderlich.
Der Schalter steuert nur das gerenderte HTML-Element (<a> im Vergleich <button>). Auch wenn QuickGrid deaktiviert ist, liest und schreibt es den Status intern weiterhin in den Query-String der URL.
SortByColumnAsync und Paginator.GoToPageAsync navigieren unabhängig vom Flag über NavigationManager.NavigateTo.
Klickereignis für Zeilen (OnRowClick)
Die QuickGrid Komponente unterstützt jetzt Zeilenklickereignisse durch den neuen OnRowClick Parameter. Wenn festgelegt, wendet das Raster automatisch geeignete Formatierungen (Cursorzeiger) an und ruft den Rückruf mit dem angeklickten Element auf:
@using Microsoft.AspNetCore.Components.QuickGrid
@inject NavigationManager NavigationManager
<QuickGrid Items="@people.AsQueryable()"
OnRowClick="@((Person args) => HandleRowClick(args))">
<PropertyColumn Property="@(p => p.Name)" />
<PropertyColumn Property="@(p => p.Email)" />
</QuickGrid>
@code {
private List<Person> people = new()
{
new(1, "Alice Smith", "alice@example.com", "Engineering"),
new(2, "Bob Johnson", "bob@example.com", "Marketing"),
new(3, "Carol Williams", "carol@example.com", "Engineering"),
};
private void HandleRowClick(Person person)
{
NavigationManager.NavigateTo($"/person/{person.Id}");
}
private record Person(int Id, string Name, string Email, string Department);
}
Die Funktion umfasst integrierte CSS-Stile, die klickbaren Zeilen über die CSS-Klasse „row-clickable“ einen Zeigercursor zuweisen und Benutzern dadurch eine klare visuelle Rückmeldung geben.
Clientseitiges Prerendering in Blazor Web App bewahrt die Kultur des Servers
Standardmäßig speichert das clientseitige Vorrendering auf dem Server (.Client-Projekt in einer Blazor Web App) die CurrentCulture und CurrentUICulture des Servers im Komponentenstatus und wendet sie auf dem Client an, bevor Satellitenassemblys geladen werden.
Apps, bei denen der Client unabhängig vom Server eine Kultur auswählen können muss, können dies mit WebAssemblyComponentsOptions.UseCultureFromServer in der Datei Blazor Web App des Program deaktivieren:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents(options =>
{
options.UseCultureFromServer = false;
});
Sitzungsdaten zwischen HTTP-Anfragen während der statischen serverseitigen Renderung (statisches SSR) beibehalten
Sitzungsdatenpersistenz liest und schreibt cookie-basierte HTTP-Sitzungswerte während des statischen serverseitigen Renderings (statischer SSR), was für Szenarien wie Einkaufswagen-IDs oder mehrstufigen Formularfortschritt nützlich ist. Im Gegensatz zur temporären Datenpersistenz (ITempData)werden Sitzungswerte nach dem Lesen nicht gelöscht. Werte bleiben über mehrere Anfragen hinweg während der gesamten Sitzungsdauer erhalten.
Die Sitzungsspeicherkonfiguration erfordert das Hinzufügen von Diensten durch Aufrufen AddSession und Anfordern der Pipelinekonfiguration mit UseSession:
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
builder.Services.AddRazorComponents();
var app = builder.Build();
app.UseSession();
Verwenden Sie beim Angeben eines Parameters das [SupplyParameterFromSession] Attribut ohne oder mit einem Schlüssel (Zeichenfolge):
[SupplyParameterFromSession]
public string? Message { get; set; }
[SupplyParameterFromSession(Name = "flash_message")]
public string? FlashMessage { get; set; }
Weitere Informationen finden Sie unter ASP.NET Core Blazor serverseitige Zustandsverwaltung.
GetUriWithHashErweiterungsmethode
Eine neue GetUriWithHash Erweiterungsmethode ermöglicht NavigationManager das einfache Erstellen von URIs mit Hashfragmenten. Diese Helfermethode bietet eine effiziente Möglichkeit, Hashfragmente ohne Speicherallokationen an die aktuelle URI anzuhängen. Im folgenden Beispiel werden zwei Anwendungsfälle veranschaulicht:
- Inlineaufruf, der zu Abschnitt 1 (
id="section-1") der gerenderten Seite springt. - Methodenaufruf, der eine Abschnitts-ID (
sectionId) empfängt und zum Abschnitt der Seite navigiert.
@inject NavigationManager Navigation
<a href="@Navigation.GetUriWithHash("section-1")">
Jump to Section 1
</a>
@code {
private void NavigateToSection(string sectionId)
{
var uri = Navigation.GetUriWithHash(sectionId);
Navigation.NavigateTo(uri);
}
}
Die Methode verwendet string.Create für eine optimale Leistung und funktioniert ordnungsgemäß mit Nicht-Root-Basis-URIs (z. B. bei Verwendung <base href="/app/">).
EnvironmentBoundary Komponente
Blazor enthält nun eine integrierte EnvironmentBoundary Komponente für das bedingte Rendering basierend auf der Hostingumgebung. Diese Komponente bietet eine konsistente Möglichkeit zum Rendern von Inhalten basierend auf der aktuellen Umgebung in serverseitigen und clientseitigen Hostingmodellen.
Die EnvironmentBoundary Komponente akzeptiert Include und Exclude Parameter zum Angeben von Umgebungsnamen. Die Komponente führt einen Abgleich ohne Beachtung der Groß- und Kleinschreibung durch und verwendet dieselbe Semantik wie EnvironmentTagHelper in MVC.
@using Microsoft.AspNetCore.Components.Web
<EnvironmentBoundary Include="Development">
<div class="alert alert-warning">
Debug mode enabled
</div>
</EnvironmentBoundary>
<EnvironmentBoundary Include="Development,Staging">
<p>Pre-production environment</p>
</EnvironmentBoundary>
<EnvironmentBoundary Exclude="Production">
<p>@DateTime.Now</p>
</EnvironmentBoundary>
MathML-Namespaceunterstützung
Blazor unterstützt jetzt MathML-Elemente im interaktiven Rendering. MathML-Elemente wie <math>, <mrow>, <mi> und <mn> werden mit document.createElementNS() unter Verwendung des richtigen Namespace (http://www.w3.org/1998/Math/MathML) erstellt, ähnlich wie SVG-Elemente verarbeitet werden:
<math>
<mrow>
<mi>x</mi>
<mo>=</mo>
<mfrac>
<mrow>
<mo>−</mo>
<mi>b</mi>
<mo>±</mo>
<msqrt>
<mrow>
<msup><mi>b</mi><mn>2</mn></msup>
<mo>−</mo>
<mn>4</mn>
<mi>a</mi>
<mi>c</mi>
</mrow>
</msqrt>
</mrow>
<mrow>
<mn>2</mn>
<mi>a</mi>
</mrow>
</mfrac>
</mrow>
</math>
Mit diesem Fix wird sichergestellt, dass MathML-Inhalte in Browsern korrekt gerendert werden, wenn sie dynamisch über Blazorden Renderer hinzugefügt werden und Probleme beheben, bei denen MathML-Elemente zuvor als normale HTML-Elemente ohne den richtigen Namespace erstellt wurden.
InvokeVoidAsync() Analyzer
Ein neuer Blazor Analyzer (BL0010) wurde hinzugefügt, der die Verwendung InvokeVoidAsync anstelle des Aufrufens von InvokeAsync<object> JavaScript-Funktionen empfiehlt, die keine Werte zurückgeben. Dieser Analyzer hilft Entwicklern, effizienteren JSInterop-Code zu schreiben.
Problematischer Code:
// ⚠️ BL0010: Use InvokeVoidAsync for JavaScript functions that don't return a value
await JSRuntime.InvokeAsync<object>("console.log", "Hello");
Empfohlener Code:
// ✅ Correct: Use InvokeVoidAsync
await JSRuntime.InvokeVoidAsync("console.log", "Hello");
Der Analysator hilft, Leistungsprobleme zu erkennen, bei denen InvokeAsync unnötigerweise zusammen mit object verwendet oder Rückgabewerte ignoriert werden, und führt Entwickler zur passenderen InvokeVoidAsync-Methode.
IComponentPropertyActivator
Blazor stellt nun IComponentPropertyActivator zur Verfügung, um anzupassen, wie [Inject] Eigenschaften von Komponenten festgelegt werden. Dies ermöglicht erweiterte Szenarien wie:
- Bereitstellen eines zusätzlichen Kontexts für die Auflösung von Eigenschaften.
- Unterstützung für benutzerdefinierte DI-Container, die die Einfügung von Eigenschaften abfangen müssen.
- Erweiterte Szenarien, die eine Anpassung von Property Injection erfordern.
public interface IComponentPropertyActivator
{
Action<IServiceProvider, IComponent> GetActivator(
[DynamicallyAccessedMembers(Component)] Type componentType);
}
Die Standardimplementierung zwischenspeichert Aktivatoren pro Komponententyp, unterstützt schlüsselbasierte Dienste über [Inject(Key = "...")], integriert sich in Hot Reload zur Cacheinvalidierung und enthält geeignete Trimminganmerkungen für die AOT-Kompatibilität.
SignalR
ConfigureConnection für Interaktive Serverkomponenten
Blazor ermöglicht nun über die neue ConfigureConnection-Eigenschaft von ServerComponentsEndpointOptions das Konfigurieren der zugrunde liegenden SignalR-Verbindungsoptionen bei der Verwendung von Interactive Server-Komponenten. Dies ermöglicht die Konfiguration der Eigenschaften von HttpConnectionDispatcherOptions, auf die zuvor nur über Workarounds zugegriffen werden konnte.
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode(options =>
{
options.ConfigureConnection = dispatcherOptions =>
{
dispatcherOptions.CloseOnAuthenticationExpiration = true;
dispatcherOptions.AllowStatefulReconnects = true;
dispatcherOptions.ApplicationMaxBufferSize = 1024 * 1024;
};
});
Dies stellt eine saubere, typsichere API zum Konfigurieren SignalR von Verbindungseinstellungen bereit, ohne Endpunktmetadaten prüfen zu müssen.
IHostedService Unterstützung in Blazor WebAssembly
Blazor WebAssembly unterstützt IHostedService jetzt die Ausführung von Hintergrunddiensten im Browser. Dies sorgt für Featureparität mit Blazor Server und ermöglicht Szenarien wie regelmäßige Datenaktualisierung, Echtzeitaktualisierungen und Hintergrundverarbeitung.
public class DataRefreshService : IHostedService
{
private Timer? _timer;
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(RefreshData, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));
return Task.CompletedTask;
}
private void RefreshData(object? state)
{
// Refresh data periodically
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Dispose();
return Task.CompletedTask;
}
}
// Registration
builder.Services.AddHostedService<DataRefreshService>();
Gehostete Dienste werden gestartet, wenn die App gestartet und beendet wird, wenn sie heruntergefahren wird, wodurch ein sauberer Lebenszyklus für Hintergrundvorgänge in Blazor WebAssembly Apps bereitgestellt wird.
Umgebungsvariablen in der Blazor WebAssembly Konfiguration
Blazor WebAssembly Anwendungen können jetzt mit IConfiguration auf Umgebungsvariablen zugreifen. Dies ermöglicht die Laufzeitkonfiguration, ohne die Anwendung neu zu erstellen, wodurch es einfacher ist, denselben Build in verschiedenen Umgebungen bereitzustellen.
Im folgenden Beispiel werden die Umgebungsvariablen API_ENDPOINT und ENABLE_FEATURE_X automatisch in die Konfiguration aufgenommen:
var builder = WebAssemblyHostBuilder.CreateDefault(args);
var apiEndpoint = builder.Configuration["API_ENDPOINT"];
var featureFlag = builder.Configuration["ENABLE_FEATURE_X"];
Umgebungsvariablen werden zusammen mit anderen Konfigurationsquellen in das Konfigurationssystem geladen, z. B. App-Einstellungen (appsettings.json), um unabhängig von ihrer Quelle auf Konfigurationswerte zuzugreifen.
Blazor WebAssembly Komponentenmetriken und Ablaufverfolgung
Blazor WebAssembly Apps stellen jetzt komponentenspezifische Metriken und Ablaufverfolgung bereit, wenn die Unterstützung für Metriken in der Laufzeit aktiviert wurde.
Containerunterstützung in der Vorlage Blazor Web App aktivieren
Die Projektvorlage Blazor Web App unterstützt jetzt die Option Enable container support in Visual Studio. Dies erleichtert die Containerisierung Blazor Web Apps und die Bereitstellung auf Container-Orchestrierungsplattformen wie Kubernetes oder Azure Container Apps.
StatischeR SSR unterstützt clientseitige Validierung
Blazor Statische serverseitige Renderingformulare (static SSR) erhalten jetzt sofortiges Feedback zur In-Browser-Validierung ohne Server-Roundtrip und entsprechen der Erfahrung, die von interaktiven Blazor Apps und MVC-Apps mit unaufdringlicher Validierung bereitgestellt wird. Das .NET Modell bleibt die einzige Quelle der Wahrheit für Validierungsregeln. Der Server erstellt Metadaten für die Validierungsregeln, die dann durch den BlazorJS-Code auf der Clientseite durchgesetzt werden.
Das Feature ist standardmäßig für alle statischen SSR-Formulare aktiviert, die die DataAnnotationsValidator Komponente enthalten. Sowohl erweiterte als auch nicht erweiterte Formulare werden unterstützt.
Die vollständige Featureabdeckung ist in ASP.NET Core Blazor Forms Validation verfügbar.
Weitere Informationen finden Sie in den folgenden Ressourcen:
-
.NET-Unterstützung für die clientseitige Validierung in Blazor SSR hinzufügen (
dotnet/aspnetcore#66441) -
Hinzufügen JS einer Bibliothek für die clientseitige Überprüfung in Blazor SSR (
dotnet/aspnetcore#66420)
Bitte kommentieren Sie keine geschlossenen Probleme und PRs. Wenn Sie Feedback zu dieser Funktion haben, eröffnen Sie bitte ein neues Issue im dotnet/aspnetcore GitHub-Repository.
Unterstützung für die asynchrone Formularüberprüfung
Blazor Formulare erhalten Unterstützung für asynchrone Gültigkeitsprüfungsregeln, z. B. Datenbanksuchvorgänge oder Remote-API-Aufrufe. In jedem Renderingmodus wartet EditForm die Validierung beim Absenden jetzt ordnungsgemäß durchgängig auf asynchrone Validatoren. In interaktiven Modi können Validatorkomponenten asynchrone Aufgaben pro Feld über EditContext.AddValidationTaskregistrieren. Das Framework verfolgt sie, bricht abgelöste Vorgänge ab und macht den Status über IsValidationPending(field) und IsValidationFaulted(field)verfügbar.
Während Preview 5 die Bausteine für Blazor-Formulare enthält, wird die vollständige integrierte asynchrone Überprüfungsoberfläche aktiviert, wenn die neuen asynchronen DataAnnotations-APIs in einer späteren .NET Vorschau veröffentlicht werden. Diese APIs werden von der vorhandenen DataAnnotationsValidator Komponente vollständig unterstützt.
<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
<InputText @bind-Value="model.Username" />
@if (editContext.IsValidationPending(() => model.Username))
{
<span>Checking availability...</span>
}
<ValidationMessage For="() => model.Username" />
<button type="submit">Register</button>
</EditForm>
@code {
[Inject] public UserService Users { get; set; } = default!;
private readonly RegistrationModel model = new();
private EditContext editContext = default!;
private ValidationMessageStore messages = default!;
protected override void OnInitialized()
{
editContext = new EditContext(model);
messages = new ValidationMessageStore(editContext);
editContext.OnFieldChanged += (_, e) =>
{
if (e.FieldIdentifier.FieldName == nameof(model.Username))
{
var cts = new CancellationTokenSource();
editContext.AddValidationTask(e.FieldIdentifier,
CheckAsync(e.FieldIdentifier, model.Username, cts.Token), cts);
}
};
}
private async Task CheckAsync(FieldIdentifier field, string value, CancellationToken ct)
{
messages.Clear(field);
if (await Users.IsUsernameTakenAsync(value, ct))
{
messages.Add(field, "Username is taken.");
}
editContext.NotifyValidationStateChanged();
}
private async Task HandleSubmit() => await editContext.ValidateAsync();
}
Die vollständige Featureabdeckung ist in ASP.NET Core Blazor Forms Validation verfügbar.
Weitere Informationen finden Sie unter Integrierte Unterstützung für die asynchrone Formularvalidierung in Blazor hinzufügen (dotnet/aspnetcore #66526).
Bitte kommentieren Sie keine geschlossenen Issues und PRs. Wenn Sie Feedback zu dieser Funktion haben, eröffnen Sie bitte ein neues Issue im GitHub-Repository dotnet/aspnetcore.
Blazor und Minimal APIs unterstützen die Lokalisierung von Fehlermeldungen
Die Validierung von Blazor Formularen und minimalen API-Endpunkten erhält erstklassige Unterstützung für die Lokalisierung von Fehlermeldungen und Eigenschaftennamen. Die Lokalisierung verwendet standardmäßig sprachspezifische RESX-Dateien, die als Teil der Assembly bereitgestellt werden.
builder.Services.AddValidation()
.AddValidationLocalization<ValidationMessages>();
// Resolves to ValidationMessages.en.resx, ValidationMessages.es.resx, ...
[ValidatableType]
public class ContactModel
{
// Values of ErrorMessage are used as localization keys.
[Required(ErrorMessage = "RequiredError")]
[EmailAddress(ErrorMessage = "EmailError")]
[Display(Name = "ContactEmail")]
public string? Email { get; set; }
}
Apps können auch benutzerdefinierte IStringLocalizerFactory Implementierungen registrieren, um die lokalisierten Zeichenfolgen aus anderen Quellen zu lesen, z. B. Datenbanken oder JSON-Dateien. Ein registrierter Benutzertyp hat Vorrang vor der standardmäßigen RESX-Lokalisierung.
builder.Services.AddValidation()
.AddValidationLocalization();
builder.Services.AddSingleton<IStringLocalizerFactory, DbStringLocalizerFactory>();
Apps können auch eine programmgesteuerte Strategie für die Lokalisierung konfigurieren und die Notwendigkeit entfernen, Lokalisierungsschlüssel für jedes Überprüfungsattribut anzugeben:
builder.Services.AddValidation()
.AddValidationLocalization<ValidationMessages>(options =>
{
options.ErrorMessageKeyProvider = ctx =>
ctx.Attribute.ErrorMessage ?? $"{ctx.Attribute.GetType().Name}_Error";
});
[ValidatableType]
public class ContactModel
{
// Looks-up localized string for 'RequiredAttribute_Error' automatically.
[Required]
public string? Username { get; set; }
}
Eine vollständige Übersicht über den Funktionsumfang finden Sie in den folgenden Artikeln:
Weitere Informationen finden Sie unter Weitere Lokalisierungsunterstützung für Microsoft. Extensions.Validation (dotnet/aspnetcore #66646).
Bitte kommentieren Sie keine geschlossenen Issues und PRs. Wenn Sie Feedback zu dieser Funktion haben, eröffnen Sie bitte ein neues Issue im GitHub-Repository dotnet/aspnetcore.
Blazor Hybrid
In diesem Abschnitt werden neue Features für Blazor Hybridbeschrieben.
Versionshinweise erscheinen in diesem Abschnitt, wenn Vorschaufunktionen verfügbar werden.
SignalR
In diesem Abschnitt werden neue Features für SignalRbeschrieben.
Minimale APIs
In diesem Abschnitt werden neue Features für minimale APIs beschrieben.
Endpunktfilter beobachten Parameterbindungsfehler
Wenn ein minimaler API-Endpunkt Filter oder Filterfabriken konfiguriert hat, wird die Filterpipeline jetzt auch ausgeführt, wenn die Parameterbindung fehlschlägt. Filter können HttpContext.Response.StatusCode == 400 lesen und durch ihren eigenen Antworttext ersetzen.
Legen Sie in der Development-Umgebung RouteHandlerOptions.ThrowOnBadRequest = false so fest, dass das Framework einen 400-Statuscode zurückgibt, den der Filter abfangen kann, anstatt BadHttpRequestException an die Entwicklerausnahmeseite weiterzugeben. Dies ist in Nicht-Development-Umgebungen bereits der Standard.
Vielen Dank @marcominerva für diesen Beitrag!
OpenAPI
In diesem Abschnitt werden neue Features für OpenAPI beschrieben.
Beschreiben Sie Binärdateiantworten
ASP.NET Core 11 bietet Unterstützung für das Generieren von OpenAPI-Beschreibungen für Vorgänge, die binäre Dateiantworten zurückgeben. Diese Unterstützung ordnet den FileContentResult Ergebnistyp einem OpenAPI-Schema mit type: string und format: binary zu.
Verwenden Sie die Produces<T>-Erweiterungsmethode mit T von FileContentResult, um den Antworttyp und den Inhaltstyp anzugeben.
app.MapPost("/filecontentresult", () =>
{
var content = "This endpoint returns a FileContentResult!"u8.ToArray();
return TypedResults.File(content);
})
.Produces<FileContentResult>(contentType: MediaTypeNames.Application.Octet);
Das generierte OpenAPI-Dokument beschreibt die Endpunktantwort wie:
responses:
'200':
description: OK
content:
application/octet-stream:
schema:
$ref: '#/components/schemas/FileContentResult'
Dies FileContentResult ist definiert in components/schemas :
components:
schemas:
FileContentResult:
type: string
format: binary
OpenAPI 3.2.0-Unterstützung (Breaking Change)
Microsoft.AspNetCore.OpenApi unterstützt jetzt OpenAPI 3.2.0 durch eine aktualisierte Abhängigkeit von Microsoft.OpenApi 3.3.1. Dieses Update enthält wesentliche Änderungen an der zugrunde liegenden Bibliothek. Weitere Informationen finden Sie im Microsoft. OpenApi-Upgradehandbuch.
Um ein OpenAPI 3.2.0-Dokument zu generieren, geben Sie die Version beim Aufrufen AddOpenApian:
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_2;
});
Nachfolgende Updates nutzen neue Funktionen in der Spezifikation 3.2.0, z. B. die Elementschemaunterstützung für Streamingereignisse.
Vielen Dank @baywet für diesen Beitrag!
HTTP QUERY in generierten OpenAPI-Dokumenten
Die OpenAPI-Dokumentgenerierung erkennt jetzt HTTP QUERY als bekannten Vorgangstyp. QUERY ist eine vorgeschlagene sichere, idempotente Methode, mit der Clients beim Beschreiben einer Suche einen Anforderungstext senden können, nützlich, wenn eine Abfrage zu groß oder zu strukturiert ist, um in eine URL einzupassen. Routing akzeptiert bereits beliebige Verbzeichenfolgen über MapMethods, und OpenAPI 3.2 fügt dem Path Item-Objekt einquery Feld hinzu, damit dies im OpenAPI-Dokument beschrieben werden kann.
Beachten Sie, dass query nur in einem OpenAPI-3.2-Dokument gültig ist. Legen Sie also OpenApiVersion in der OpenApiOptions-Datei fest. In früheren OpenAPI-Versionen wird der query Vorgang innerhalb einer x-oai-additionalOperations Spezifikationserweiterung im Path Item-Objekt generiert.
using Microsoft.OpenApi;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_2;
});
var app = builder.Build();
app.MapOpenApi();
app.MapMethods("/search", ["QUERY"], (SearchRequest request) =>
SearchService.Run(request));
app.Run();
In einem OpenAPI 3.2-Dokument wird der QUERY-Vorgang inline als gleichgeordnetes Element von get, postund anderen Standardvorgängen beschrieben:
"paths": {
"/search": {
"query": {
"requestBody": { ... },
"responses": { "200": { ... } }
}
}
}
In OpenAPI 3.0- und 3.1-Dokumenten wird derselbe Vorgang unter der x-oai-additionalOperations Erweiterung für das Pfadelement dargestellt:
"paths": {
"/search": {
"x-oai-additionalOperations": {
"QUERY": {
"requestBody": { ... },
"responses": { "200": { ... } }
}
}
}
}
Vielen Dank @kilifu für diesen Beitrag!
Dateidatenstrom-Ergebnistypen werden in OpenAPI-Dokumenten angezeigt
FileStreamResult, FileContentHttpResultund FileStreamHttpResult werden jetzt als binäre Zeichenfolgenschemas in generierten OpenAPI-Dokumenten beschrieben, sodass Clients genaue Antwort-Shapes für Endpunkte sehen, die Dateien streamen. Kommentieren Sie den Endpunkt mit .Produces<FileContentHttpResult>(contentType: "application/pdf") (oder dem entsprechenden FileStreamHttpResult/FileStreamResult Typ), damit OpenAPI den Ergebnistyp sieht und das binäre Schema ausgibt.
Vielen Dank @marcominerva für diesen Beitrag!
OpenAPI-Schemas entsprechen dem Verhalten von ASP.NET Core besser
Die OpenAPI-Generierung behandelt jetzt mehrere Schemafälle genauer. Enumerationsparameter außerhalb des Anforderungstexts behalten die ursprünglichen Namen der C#-Enumerationsmitglieder bei, auch wenn HTTP-JSON-Optionen eine JsonStringEnumConverter-Benennungsrichtlinie konfigurieren, da die Bindung von Abfragezeichenfolge, Route, Header und Formular Enum.TryParse statt der JSON-Serialisierung verwendet. Referenz-IDs für Array-Schemas verwenden jetzt gültige Komponentennamen wie stringArray und TodoArray anstelle von Namen mit Array-Syntax.
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Converters.Add(
new JsonStringEnumConverter(JsonNamingPolicy.KebabCaseLower));
});
app.MapGet("/orders", (OrderStatus status) => Results.Ok(status));
Bei dieser Konfiguration kann ein Textkörperschema weiterhin als OrderStatus.PendingReviewbeschrieben werdenpending-review, während das Abfrageparameterschema den akzeptierten Wert als PendingReviewbeschreibt.
Minimale API-Endpunkte können mehrere Produces Erweiterungsmethodeaufrufe für denselben Statuscode unterstützen, um z. B. anzugeben, dass eine 200-Antwort als application/json oder text/plain mit verschiedenen Schemas eintreffen kann. Die gleiche Unterstützung gilt für MVC-Controller über mehrere [ProducesResponseType] Attribute.
In früheren Versionen hat das Framework jeden Statuscode auf einen einzelnen Antworttyp reduziert und den Rest im Hintergrund gelöscht, wodurch es unmöglich ist, Endpunkte zu beschreiben, die mehrere Inhaltstypen bereitstellen.
Microsoft.AspNetCore.Mvc.ApiExplorer behält nun jeden deklarierten Antworttyp mit deterministischer Sortierung bei, und das generierte OpenAPI-Dokument gibt separate Inhaltseinträge pro Medientyp aus – oder ein anyOf Schema, wenn mehrere Typen denselben Inhaltstyp verwenden.
Vielen Dank @marcominerva für den Beitrag zur Matrixschemareferenz!
Authentifizierung und Autorisierung
In diesem Abschnitt werden neue Features für Authentifizierung und Autorisierung beschrieben.
TimeProvider-Unterstützung in ASP.NET Core Identity
ASP.NET Core Identity verwendet jetzt TimeProvider anstelle von DateTime und DateTimeOffset für alle zeitbezogenen Vorgänge. Diese Änderung macht Identity Komponenten testfähiger und bietet eine bessere Kontrolle über die Zeit in Tests und spezialisierten Szenarien.
Das folgende Beispiel zeigt, wie Sie eine gefälschte TimeProvider zum Testen der Funktionen von Identity verwenden können:
// In tests
var fakeTimeProvider = new FakeTimeProvider(
new DateTimeOffset(2024, 1, 1, 0, 0, 0, TimeSpan.Zero));
services.AddSingleton<TimeProvider>(fakeTimeProvider);
services.AddIdentity<IdentityUser, IdentityRole>();
// Identity will now use the fake time provider
Mithilfe von TimeProvider können Sie deterministische Tests für zeitkritische Identity Funktionen wie Tokenablauf, Sperrdauern und Sicherheitsstempelüberprüfung einfacher schreiben.
Anzeigename für Passkeys vom Authentifikator ableiten
ASP.NET Core Identity leitet jetzt automatisch freundliche Anzeigenamen für Passkeys auf der Grundlage ihrer AAGUID (Authenticator Attestation GUID) ab. Integrierte Zuordnungen sind für die am häufigsten verwendeten Passkey-Authentifikatoren enthalten, einschließlich Google Password Manager, iCloud-Schlüsselbund, Windows Hello, 1Password und Bitwarden.
Bei bekannten Authentifikatoren wird der Name automatisch zugewiesen, ohne den Benutzer aufzufordern. Bei unbekannten Authentifikatoren wird der Benutzer zu einer Umbenennungsseite umgeleitet. Erweitern Sie die Zuordnungen, indem Sie Einträge zum PasskeyAuthenticators-Wörterbuch im Projekt hinzufügen.
Miscellaneous
In diesem Abschnitt werden verschiedene neue Features in .NET 11 beschrieben.
IOutputCachePolicyProvider-Schnittstelle
ASP.NET Core in .NET 11 stellt die Schnittstelle IOutputCachePolicyProvider zum Implementieren von Logik zur Auswahl benutzerdefinierter Richtlinien für die Ausgabezwischenspeicherung bereit. Mithilfe dieser Schnittstelle können Apps die Standardrichtlinie für die Basiszwischenspeicherung ermitteln, das Vorhandensein benannter Richtlinien überprüfen und erweiterte Szenarien unterstützen, in denen Richtlinien dynamisch aufgelöst werden müssen. Beispiele hierfür sind das Laden von Richtlinien aus externen Konfigurationsquellen, Datenbanken oder das Anwenden mandantenspezifischer Zwischenspeicherungsregeln.
Der folgende Code zeigt die IOutputCachePolicyProvider Schnittstelle:
public interface IOutputCachePolicyProvider
{
IReadOnlyList<IOutputCachePolicy> GetBasePolicies();
ValueTask<IOutputCachePolicy?> GetPolicyAsync(string policyName);
}
Vielen Dank @lqlive für diesen Beitrag!
Entwicklungszertifikaten in WSL automatisch vertrauen
Die Konfiguration des Entwicklungszertifikats vertraut jetzt automatisch Zertifikaten in WSL-Umgebungen (Windows-Subsystem für Linux). Wenn Sie dotnet dev-certs https --trust in WSL ausführen, wird das Zertifikat automatisch installiert und sowohl in der WSL-Umgebung als auch in Windows als vertrauenswürdig eingestuft, wodurch die manuelle Vertrauenskonfiguration eliminiert wird.
# Automatically trusts certificates in both WSL and Windows
dotnet dev-certs https --trust
Diese Verbesserung optimiert die Entwicklungserfahrung bei der Verwendung von WSL und entfernt einen gemeinsamen Reibungspunkt für Entwickler, die in Linux-Umgebungen auf Windows arbeiten.
Vielen Dank @StickFun für diesen Beitrag!
Natives OpenTelemetry-Tracing für ASP.NET Core
ASP.NET Core fügt nun native OpenTelemetry-Semantikkonventionsattribute zur HTTP-Serveraktivität hinzu, die an der OpenTelemetry HTTP Server Span Specification ausgerichtet ist. Alle erforderlichen Attribute sind standardmäßig enthalten und entsprechen den zuvor nur über die OpenTelemetry.Instrumentation.AspNetCore Bibliothek verfügbaren Metadaten.
Um die integrierten Tracing-Daten zu erfassen, abonnieren Sie die Microsoft.AspNetCore-Aktivitätsquelle in Ihrer OpenTelemetry-Konfiguration:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource("Microsoft.AspNetCore")
.AddConsoleExporter());
Es ist keine zusätzliche Instrumentierungsbibliothek (wie OpenTelemetry.Instrumentation.AspNetCore) erforderlich. Das Framework füllt nun direkt semantische Konventionsattribute in der Anforderungsaktivität aus, wie z. B. http.request.method, url.path, http.response.status_code und server.address.
Wenn Der Aktivität keine OpenTelemetry-Attribute hinzugefügt werden sollen, können Sie sie deaktivieren, indem Sie den Schalter Microsoft.AspNetCore.Hosting.SuppressActivityOpenTelemetryData AppContext auf true festlegen.
Leistungsverbesserungen
Der HTTP/1.1-Anfrageparser von Kestrel verwendet jetzt einen Code-Pfad, der keine Ausnahmen auslöst, um fehlerhafte Anfragen zu verarbeiten. Anstatt bei jedem Parsing-Fehler einen BadHttpRequestException-Fehler auszugeben, gibt der Parser eine Ergebnisstruktur zurück, die den Status „erfolgreich“, „unvollständig“ oder „Fehler“ angibt. In Szenarien mit vielen falsch formatierten Anforderungen – z. B. Portüberprüfung, böswilliger Datenverkehr oder falsch konfigurierten Clients – beseitigt dies teure Ausnahmebehandlungsaufwand und verbessert den Durchsatz um bis zu 20-40%. Es gibt keine Auswirkungen auf die gültige Anforderungsverarbeitung.
Die HTTP-Protokollierungs-Middleware bündelt jetzt ihre ResponseBufferingStream-Instanzen und reduziert so die Zuweisungen pro Anfrage, wenn die Protokollierung des Antworttextes oder Interceptoren aktiviert sind.
Zstandard-Antwortkomprimierung und Anforderungsdekomprimierung
ASP.NET Core unterstützt jetzt Zstandard (zstd) sowohl für die Antwortkomprimierung als auch für die Anforderungsenkomprimierung. Dadurch wird der vorhandenen Middleware zur Antwortkomprimierung und Dekomprimierung von Anfragen Unterstützung für zstd hinzugefügt und zstd standardmäßig aktiviert.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResponseCompression();
builder.Services.AddRequestDecompression();
builder.Services.Configure<ZstandardCompressionProviderOptions>(options =>
{
options.CompressionOptions = new ZstandardCompressionOptions
{
Quality = 6 // 1-22, higher = better compression, slower
};
});
Vielen Dank @manandre für diesen Beitrag!
HTTP/3 beginnt mit der Verarbeitung von Anforderungen früher
Kestrel beginnt jetzt mit der Verarbeitung von HTTP/3-Anforderungen, ohne zuerst auf den Steuerdatenstrom und den SETTINGS-Frame zu warten, wodurch die Latenz der ersten Anforderung bei neuen Verbindungen reduziert wird.
MCP Server-Vorlage wird mit dem .NET SDK ausgeliefert.
Die Projektvorlage mcpserver, die zuvor nur durch die Installation von Microsoft.McpServer.ProjectTemplates verfügbar war, wird nun als gebündelte Vorlage im .NET SDK bereitgestellt:
dotnet new mcpserver -o MyMcpServer
Wenn Sie die Vorlage in ASP.NET Core verschieben, kann sie von dotnet new list ohne einen separaten Installationsschritt auffindbar sein und die Wartung am rest des Webstapels ausrichten.
Beobachtbarkeit des TLS-Handshakes in Kestrel
Zwei verwandte Änderungen erleichtern das Diagnostizieren und Anpassen von TLS-Verbindungen in Kestrel.
ITlsHandshakeFeature stellt nun eine Exception-Eigenschaft bereit, die die Ausnahme enthält, die bei einem fehlgeschlagenen TLS-Handshake ausgelöst wurde, sodass Middleware und Protokollierung erfassen können, warum eine Verbindung fehlgeschlagen ist, anstatt weiter oben im Stack nur ein bloßes IOException zu sehen. Das Feature funktioniert auch nach einem fehlgeschlagenen Handshake weiterhin — Kestrel erstellt eine Momentaufnahme der relevanten Felder des zugrunde liegenden SslStream, bevor es freigegeben wird.
Die TlsClientHelloBytesCallback-Option auf HttpsConnectionAdapterOptions wurde zu einer Verbindungs-Middleware umgestaltet. Das vorherige Callback-Format ist nun obsolet; konfigurieren Sie die ClientHello-Inspektion stattdessen über die neue ListenOptions.UseTlsClientHelloListener-Erweiterung. Im folgenden Beispiel werden beide Features gemeinsam verwendet: Verbindungs-Middleware liest ITlsHandshakeFeature.Exception nach dem Handshake und UseTlsClientHelloListener prüft den ClientHello vor TLS:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.Use(next => async context =>
{
await next(context);
var tlsHandshakeFeature = context.Features.Get<ITlsHandshakeFeature>();
if (tlsHandshakeFeature?.Exception is { } ex)
{
Console.WriteLine($"[TLS Handshake Failed] ConnectionId={context.ConnectionId}, Exception={ex.GetType().Name}: {ex.Message}");
}
});
// UseTlsClientHelloListener must be called before UseHttps()
listenOptions.UseTlsClientHelloListener((connection, clientHelloBytes) =>
{
Console.WriteLine($"TLS Client Hello received on {connection.ConnectionId}, {clientHelloBytes.Length} bytes");
});
listenOptions.UseHttps();
});
});
Die Antwortkomprimierung gibt immer Vary: Accept-Encoding aus.
Die Middleware für die Reaktionskomprimierung fügt Vary: Accept-Encoding jetzt zu jeder Antwort hinzu, wenn die Komprimierung aktiviert ist, auch wenn die Antwort selbst nicht komprimiert wird. Dadurch wird verhindert, dass gemeinsam genutzte Caches und CDNs eine komprimierte Nutzlast an einen Client bereitstellen, der nicht um einen (oder umgekehrt) gebeten hat.
Vielen Dank @pedrobsaila für diesen Beitrag!
Runtime-async für freigegebene Frameworkbibliotheken aktiviert
Die Bibliotheken von ASP.NET Core, die nur im freigegebenen Framework enthalten sind, werden jetzt auf runtime-async mit dem Feature net11.0+ kompiliert. Runtime-async ermöglicht es der Laufzeit, anstelle des C#-Compilers die Zustandsmaschine für async/await zu generieren, was die Speicherzuweisungen pro await reduzieren und die Diagnose verbessern kann. Dies ist eine interne Codegenerierungsänderung ohne Auswirkungen auf die öffentliche API – Apps, die net11.0 als Ziel verwenden, profitieren automatisch davon, wenn sie die betroffenen ASP.NET Core-Bibliotheken aufrufen.
Bibliotheken, die sowohl als Bestandteile eines Shared Frameworks als auch als eigenständige NuGet-Pakete ausgeliefert werden, sind ausgenommen, da runtime-async nicht mit WebAssembly kompatibel ist und andernfalls Wasm-Nutzer dieser Pakete unbrauchbar machen würde.
Weil runtime-async die Art ändert, wie async/await für große Teile des ASP.NET Core-Stacks generiert wird, testen Sie Ihre Apps mit dieser Vorschau, und melden Sie ein Problem, wenn Sie auf unerwartetes Verhalten stoßen, insbesondere bei Exception-Stacks, ExecutionContext/AsyncLocal-Abläufen oder allem, was wie eine Regression gegenüber .NET 10 aussieht.
Middleware zur Ratenbegrenzung liefert genaue Retry-After Kopfzeilen.
FixedWindowRateLimiter meldet jetzt einen Metadatenwert RetryAfter, der die Grenze des nächsten Fensters präzise wiedergibt. Apps, die diese Metadaten in ihrem Retry-After Rückruf an den OnRejected Antwortheader weitergeben, erzeugen jetzt automatisch korrekte Wiederholungsintervalle, ohne dass Codeänderungen erforderlich sind.
Zusätzliche Korrekturen in System.Threading.RateLimiting beheben ein Problem, bei dem TokenBucketRateLimiter partielle Token-Auffüllungen beim Erwerb von null Permits falsch behandelte, und verbessern den von CreateChained zurückgegebenen verketteten Rate-Limiter, sodass Leerlaufdauer und Auffüllverhalten seiner inneren Limiter korrekt weitergeleitet werden.
Eine Übersicht über die Rate limitierende Middleware finden Sie unter Rate limiting middleware in ASP.NET Core.
Vielen Dank @asbjornvad und @apoorvdarshan für diese Beiträge!
Kestrel wendet Zeitüberschreitungen für Trailer-Header an
Kestrel wird jetzt auf RequestHeadersTimeout fragmentierte HTTP/2- und HTTP/3-Trailer-Header angewendet, die die Übertragung des Header-Blocks nicht abschließen. Dasselbe Timeout, das die Header der ursprünglichen Anfrage schützt, verhindert jetzt auch, dass Verbindungen unbegrenzt offen bleiben, während Kestrel auf den Abschluss der Trailer-Frames HEADERS wartet.
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
});
Bahnbrechende Änderungen
Verwenden Sie die Artikel in Breaking changes in .NET, um wesentliche Änderungen zu finden, die beim Upgrade einer Anwendung auf eine neuere Version von .NET zutreffen könnten.