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 Zeitüberschreitung 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 keine geschlossenen Probleme und PRs kommentieren)
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.Bei den Updates wird ein hybrider Ansatz verwendet: native CSS-Bildlaufverankerung in Browsern, die diese Funktion für Layouts ohne
<table>unterstützen, mit einem manuellen, aufResizeObserverbasierenden basierenden Fallback zur Bildlaufkompensation für<table>-Layouts und Safari, wo die native Verankerung die Positionen von<tr>-Elementen 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. -
Start(Standard): Heftet den Viewport an den Anfang der Liste an. Zum Beispiel ist dieses Anheftungsverhalten für das Nutzungserlebnis in einem Newsfeed nützlich. -
End: Fixiert den Viewport am Ende der Liste. Zum Beispiel ist dieses Anheftungsverhalten für eine Chat- oder Protokollierungserfahrung nützlich.
Im folgenden Beispiel wird der virtualisierte Inhalt an den Anfang der Liste angeheftet:
<Virtualize AnchorMode="Start" ...> ... </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 keine geschlossenen Probleme und PRs kommentieren)
-
Einhaltung der Content Security Policy (CSP)
Die
Virtualize-Komponente rendert dynamische Inline-style-Attribute für ihre Abstands- und Platzhalterelemente (z. B.style="height: 478896px; flex-shrink: 0;"), da die Höhe der Abstandselemente zur Laufzeit anhand der Scrollposition, der Anzahl der Elemente und der durchschnittlichen Elementgröße berechnet wird, die sich bei jeder Scroll-Interaktion ändern. Diese werden von einer Content Security Policy (CSP) blockiert, wennstyle-src 'self'festgelegt ist, wodurch die Virtualisierung für Anwendungen mit strengen CSP-Richtlinien vollständig außer Kraft gesetzt wird.Nun werden CSP-Verstöße vermieden, da
Virtualize-Komponenten:- Berechnete Abstandshalter- und Platzhalterhöhen als numerische Werte in den Attributen von
data-blazor-virtualize-reserved-heightrendern. - Falls erforderlich, geben Sie den vertikalen Versatz des nachgestellten Abstandhalters als numerischen Wert in einem
data-blazor-virtualize-loop-breaker-transform-Attribut an, um den Abstandhalter auszublenden.
- Berechnete Abstandshalter- und Platzhalterhöhen als numerische Werte in den Attributen von
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 Anhalten und Fortsetzen von Leitungen mit Blazor.pauseCircuit() und Blazor.resumeCircuit(). .NET 11 führt eine symmetrische serverseitige Funktion zum Anhalten und Fortsetzen ein, bei der der Server anfordern kann, dass verbundene Clients den Flow zum ordnungsgemäßen Anhalten von Leitungen starten.
Circuit.RequestCircuitPauseAsync(CancellationToken) wird verwendet, um anzufordern, dass der verbundene Client den Flow zum ordnungsgemäßen Anhalten von Leitungen 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.
- Instanzenausgleich.
- 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 Metrik- und Ablaufverfolgungsaufrufpfade ausRendererund verwandten Typen entfernen kann, wennSystem.Diagnostics.Metrics.Meter.IsSupportedauffalsefestgelegt ist (Standardwert für getrimmte Apps) [browser][wasm] IL-Trimmen für OTEL implementieren (dotnet/aspnetcore#65901) (bitte keine geschlossenen Probleme und PRs kommentieren). -
HotReloadManagerstellt nun eineIsSupported-Eigenschaft mit Funktionssteuerung bereit, 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 keine geschlossenen Probleme und PRs kommentieren).
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. Der 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: 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 Raster dürfen sich keinen PaginationState teilen, wenn sie unterschiedliche Präfixe haben – das zuletzt zu rendernde Raster ü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. Das erste QuickGrid verwendet das standardmäßige Präfix der leeren Zeichenfolge, während beim 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 eines Headers @onclick aus, wodurch SortByColumnAsync aufgerufen wird. 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 des Title einer Spalte ist eine Änderung, die URLs beeinträchtigen kann. 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.
Breaking Change für CSS
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.
Zeilenklickereignis (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 über die CSS-Klasse „row-clickable“ einen Zeiger-Cursor auf anklickbare Zeilen anwenden und den Benutzern so ein klares visuelles Feedback geben.
Clientseitiges Prerendering in Blazor Web App bewahrt die Kultur des Servers
Standardmäßig speichert das clientseitige Prerendering 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 der Program deaktivieren:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents(options =>
{
options.UseCultureFromServer = false;
});
Beibehaltung der Sitzungsdaten zwischen HTTP-Anfragen beim statischen serverseitigen Rendering (Static SSR)
Sitzungsdatenpersistenz liest und schreibt cookie-basierte HTTP-Sitzungswerte während des statischen serverseitigen Renderings (statisches 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.
GetUriWithFragmentErweiterungsmethode
Eine neue GetUriWithFragment Erweiterungsmethode ermöglicht NavigationManager das einfache Erstellen von URIs mit Hashfragmenten. Diese Hilfemethode bietet eine effiziente Möglichkeit, Hashfragmente ohne Speicherzuweisung an den aktuellen 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.GetUriWithFragment("section-1")">
Jump to Section 1
</a>
@code {
private void NavigateToSection(string sectionId)
{
var uri = Navigation.GetUriWithFragment(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/">).
EnvironmentView Komponente
Blazor enthält nun eine integrierte EnvironmentView 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 EnvironmentView 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
<EnvironmentView Include="Development">
<div class="alert alert-warning">
Debug mode enabled
</div>
</EnvironmentView>
<EnvironmentView Include="Development,Staging">
<p>Pre-production environment</p>
</EnvironmentView>
<EnvironmentView Exclude="Production">
<p>@DateTime.Now</p>
</EnvironmentView>
MathML-Namespaceunterstützung
Blazor unterstützt jetzt MathML-Elemente im interaktiven Rendering. MathML-Elemente wie <math>, <mrow>, <mi> und <mn> werden mit http://www.w3.org/1998/Math/MathML unter Verwendung des richtigen Namespace (document.createElementNS()) 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 bereit, um anzupassen, wie [Inject]-Eigenschaften für Komponenten gefüllt 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 das Einschleusen 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 SignalR-Eigenschaft von ConfigureConnection das Konfigurieren der zugrunde liegenden ServerComponentsEndpointOptions-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.
Konfigurieren Sie das Client-Verhalten von Blazor über den Server
Blazor-Apps können nun beim Zuordnen von Razor-Komponenten das clientseitige Startverhalten aus dem Server in C# konfigurieren, anstatt Blazor.start-JavaScript manuell zu schreiben.
WithBrowserOptions legt Optionen fest, die der Server in die gerenderte Seite serialisiert, und das Blazor Skript gilt im Browser über den Server-, WebAssembly- und automatischen Rendermodus. Die Optionen decken die Clientprotokollebene, die interaktive Serververbindung ab, ob die erweiterte Navigation das DOM behält, und den Umgebungsnamen, die Kultur und umgebungsvariablen einer WebAssembly-Laufzeit:
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.WithBrowserOptions(options =>
{
options.LogLevel = LogLevel.Warning;
options.Server.ReconnectionMaxRetries = 10;
options.Server.ReconnectionRetryInterval = TimeSpan.FromSeconds(1.5);
options.Ssr.PreserveDom = true;
options.WebAssembly.EnvironmentName = "Staging";
options.WebAssembly.EnvironmentVariables["OTEL_EXPORTER_OTLP_ENDPOINT"] =
"https://localhost:4318";
});
Sie können die Optionen auch in einer Komponente mit <ConfigureBrowser> festlegen oder die aufgelösten Optionen aus HttpContext mit GetBrowserOptions() auslesen.
Die API wurde in Preview 4 eingeführt und in Preview 6 umgestaltet, um den Optionenkonventionen zu entsprechen. Wenn Sie die frühere Form verwendet haben, gilt WithBrowserConfiguration jetzt als WithBrowserOptions, BrowserConfiguration jetzt als BrowserOptions, ServerBrowserOptions jetzt als InteractiveServerBrowserOptions, SsrBrowserOptions.DisableDomPreservation jetzt als PreserveDom (mit umgekehrter Bedeutung) und CircuitInactivityTimeoutMs jetzt als CircuitInactivityTimeout (ein TimeSpan).
Weitere Informationen finden Sie in den folgenden Ressourcen:
-
API-Vorschlag: BrowserOptions für die Server-zu-Client-Konfiguration (
dotnet/aspnetcore#66393) -
BrowserConfiguration-API pro Überprüfung (BrowserOptions) neugestalten unter Beibehaltung des JS-Übertragungsformats (
dotnet/aspnetcore#67337)
Bitte kommentieren Sie keine geschlossenen Probleme und PRs. Öffnen Sie ein neues Problem, um Feedback zu dieser API zu geben.
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 die EditForm-Absendeprüfung jetzt ordnungsgemäß und durchgängig auf asynchrone Validatoren. In interaktiven Modi können Validator-Komponenten eine asynchrone Validierung pro Feld über EditContext.RegisterAsyncFieldValidator registrieren. Das Framework verfolgt diese, bricht überholte Validierungen ab und stellt den Fortschrittsstatus über IsValidationPending(field) und IsValidationFaulted(field) bereit.
Die integrierte DataAnnotationsValidator Komponente führt die asynchronen APIs (AsyncValidationAttribute und IAsyncValidatableObject) aus, sodass asynchrone DataAnnotations Regeln, die für das Modell deklariert wurden, ohne zusätzliche Konfiguration funktionieren.
<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))
{
editContext.RegisterAsyncFieldValidator(e.FieldIdentifier,
token => CheckAsync(e.FieldIdentifier, model.Username, token));
}
};
}
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 Probleme und PRs. Wenn Sie Feedback zu dieser Funktion haben, eröffnen Sie bitte ein neues Issue im dotnet/aspnetcore GitHub-Repository.
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 wird automatisch aktiviert, sobald eine IStringLocalizerFactory verfügbar ist. Standardmäßig wird die von AddLocalization registrierte Lokalisierung mithilfe sprachspezifischer RESX-Dateien bereitgestellt, die als Teil der Assembly bereitgestellt werden.
builder.Services.AddLocalization();
builder.Services.AddValidation();
[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.AddSingleton<IStringLocalizerFactory, DbStringLocalizerFactory>();
builder.Services.AddValidation();
Um Schlüssel aus einer gemeinsam genutzten Ressourcendatei anstelle der eigenen Ressourcen des validierten Typs zu beheben, legen Sie ValidationOptions.LocalizerProvider fest:
builder.Services.AddValidation(options =>
{
options.LocalizerProvider = (_, factory) => factory.Create(typeof(ValidationMessages));
});
Wenn ein Attribut ErrorMessage nicht setzt, werden konventionelle Suchschlüssel in der Reihenfolge vom spezifischsten bis zum allgemeinsten ausprobiert, sodass es nicht mehr erforderlich ist, für jedes Validierungsattribut Lokalisierungsschlüssel anzugeben:
[ValidatableType]
public class ContactModel
{
// Looks up 'ContactModel_Username_RequiredAttribute_Error', then
// 'ContactModel_RequiredAttribute_Error', then 'RequiredAttribute_Error'.
[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 Probleme und PRs. Wenn Sie Feedback zu dieser Funktion haben, eröffnen Sie bitte ein neues Issue im dotnet/aspnetcore GitHub-Repository.
Fehlerbehebungen bei TempData und [SupplyParameterFromSession]-Persistenz für SSR-Streaming
Wenn eine Seite sitzungsgestützte Features verwendet, bei denen eine Komponente über einen [SupplyParameterFromSession] Parameter verfügt (der ein Abonnement erstellt) oder der TempData-Anbieter des Sitzungsspeichers aktiv ist, wird die Sitzung cookie (.AspNetCore.Session) jetzt ausgegeben, bevor das Streaming beginnt, auch wenn letztendlich kein Wert geschrieben wird. Seiten, die keine sitzungsbasierten Funktionen verwenden, sind davon nicht betroffen.
Weitere Informationen finden Sie unter Fehlerbehebung bei TempData und SupplyParameterFromSession-Persistenz im Falle von SSR-Streaming (dotnet/aspnetcore #66832). (Bitte kommentieren Sie keine geschlossenen Probleme und PRs.)
Antiforgery-Middleware (app.UseAntiforgery()) optional in Blazor Web Apps
CSRF-Schutz ist standardmäßig über die automatisch eingefügte CSRF-Schutz-Middleware aktiviert, sodass der explizite Aufruf in app.UseAntiforgery() Vorlagen optional ist, es sei denn, in bestimmten Anwendungsfällen ist der explizite Blazor Web App Aufruf in Vorlagen erforderlich. In einer zukünftigen Vorschauversion wird die Middleware aus der Anforderungsverarbeitungspipeline für Apps entfernt, die aus der Blazor Web App Projektvorlage erstellt wurden.
Weitere Informationen finden Sie in den folgenden Ressourcen:
- Migrieren von ASP.NET Core in .NET 10 zu ASP.NET Core in .NET 11
- Blazor Serverseitiges Rendering verlagert die Antifälschungsvalidierung in die Middleware (Ankündigung einer kompatibilitätsbrechenden Änderung)
Allgemeine Abdeckung für den neuen automatischen CSRF-Schutz in ASP.NET Core:
- Verhindern Sie websiteübergreifende Anforderungsfälschungsangriffe (XSRF/CSRF) in ASP.NET Core
- Übersicht über ASP.NET Core Blazor-Formulare
- ASP.NET Core Blazor Authentifizierung und Autorisierung
Blazor Virtualize kann zu einem Element scrollen
Die Virtualize<TItem> Komponente kann jetzt bei einem bestimmten Element geöffnet werden und zu einem beliebigen Element bei Bedarf scrollen. Zwei neue öffentliche APIs ermöglichen dies:
-
InitialItemIndexpositioniert die Liste an einem bestimmten Element beim ersten interaktiven Rendern, sodass die Liste an diesem Element geöffnet wird, ohne dass das erste Element blinkt. -
ScrollToIndexAsync(int itemIndex, CancellationToken cancellationToken = default)scrollt jederzeit nach dem ersten Rendern zu einem Element und gibt einTaskzurück, das abgeschlossen wird, sobald das Ziel am oberen Rand des Viewports ausgerichtet ist.
<Virtualize TItem="Product" Items="products" InitialItemIndex="500" @ref="list">
<div class="product">@context.Name</div>
</Virtualize>
<button @onclick="GoToTop">Back to top</button>
@code {
private Virtualize<Product> list = default!;
private List<Product> products = ProductCatalog.All;
private async Task GoToTop() => await list.ScrollToIndexAsync(0);
}
Indizes außerhalb des gültigen Bereichs werden auf den gültigen Bereich begrenzt. Wenn ein zweiter ScrollToIndexAsync-Aufruf beginnt, während noch ein anderer ausgeführt wird, gewinnt der letzte Aufruf. Das Aufrufen von ScrollToIndexAsync vor dem ersten interaktiven Rendern löst InvalidOperationException aus; verwenden Sie stattdessen InitialItemIndex, um die Startposition festzulegen.
Weitere Informationen finden Sie unter InitialIndex-Parameter (sic) und ScrollToIndexAsync-API zu Virtualize<TItem> hinzufügen (dotnet/aspnetcore #66753). (Bitte kommentieren Sie keine geschlossenen Probleme und PRs.)
Automatische Pause des Ablaufs bei Inaktivität des Tabs
Die automatische Pause-Funktion kann einen Circuit anhalten, wenn der Browser-Tab ausgeblendet wird, wodurch Arbeitsspeicher und SignalR-Verbindungen freigegeben werden, die von inaktiven Benutzern belegt sind. Es ist eine optionale Funktion, die vom Paket Microsoft.AspNetCore.Components.Server.AutoPause bereitgestellt wird. Aktivieren Sie die Funktion nach dem Hinzufügen einer Paketreferenz, indem Sie AddAutoPause aufrufen, sobald die Stammkomponente der App zugeordnet ist:
app.MapRazorComponents<App>()
.WithBrowserOptions(options => options.AddAutoPause(p => p.HiddenDelay = TimeSpan.FromSeconds(30)));
Nachdem die Registerkarte für eine konfigurierbare Verzögerungszeit ausgeblendet wurde (Standard: 2 Minuten), pausiert der Kreislauf. Wenn der Benutzer zurückkehrt, bevor die Verzögerung abläuft, wird die Pause nicht ausgelöst.
Weitere Informationen finden Sie unter ASP.NET Core Blazor serverseitige Zustandsverwaltung.
Breitere Unterstützung für AuthorizationPolicy und IAuthorizationRequirementData
Ab .NET 11 können Sie SignalR-Attribute auf Blazor-Hubs und Hubmethoden, MVC-Controller und -Aktionen sowie auf die AuthorizeRouteView- und IAuthorizationRequirementData-Komponenten von AuthorizeView anwenden, nicht nur auf Endpunkte. Für Apps, die auf Versionen vor .NET 11 abzielen, werden diese Attribute nur bei Minimal-API- und routingbasierten Endpunkten erzwungen.
Weitere Informationen finden Sie unter Benutzerdefinierte Autorisierungsrichtlinien mit "IAuthorizationRequirementData".
QuickGrid APIs aus Virtualize werden verfügbar gemacht
Die folgenden neuen QuickGrid Komponenten-APIs werden verfügbar gemacht, wenn ein Raster virtualisiert wird (Virtualize festgelegt auf true):
-
InitialItemIndex: Scrollt das Raster zum angegebenen nullbasierten Zeilenindex im ersten interaktiven Rendern. Der Wert wird einmal angewendet und auf den gültigen Bereich fixiert. Dies wird an die innereVirtualizeKomponente weitergeleitet. Weitere Informationen finden Sie unter Razor-Komponentenvirtualisierung in ASP.NET Core. -
ScrollToItemAsync: Scrollt das Raster programmgesteuert zum angegebenen, nullbasierten Zeilenindex und richtet es am oberen Rand aus. Der letzte Aufruf hat Vorrang, und die Methode löst einen InvalidOperationException aus, wenn die Virtualisierung deaktiviert ist oder das Raster noch nicht gerendert wurde. Dies wird an die innereVirtualizeKomponente weitergeleitet. Weitere Informationen finden Sie unter Razor-Komponentenvirtualisierung in ASP.NET Core. -
AnchorMode: Steuert, wie sich der Viewport an Listenrändern verhält, wenn Elemente dynamisch hinzugefügt werden (Standard:Start). Dies ist eine experimentelle API, die die ausdrückliche Aktivierung derASP0030-Diagnose erfordert und an die interneVirtualize-Komponente weiterleitet. Weitere Informationen finden Sie unter Razor-Komponentenvirtualisierung in ASP.NET Core. -
ItemComparer: Ein Vergleicher, mit dem erkannt wird, ob Elemente zwischen Datenladungen vorangestellt oder angehängt wurden; dies ist nützlich für klassenbasierte Elemente, die von einem ItemsProvider bereitgestellt werden. Dies ist eine experimentelle API, die die ausdrückliche Aktivierung derASP0030-Diagnose erfordert und an die interneVirtualize-Komponente weiterleitet. Weitere Informationen finden Sie unter Razor-Komponentenvirtualisierung in ASP.NET Core.
Weitere Informationen finden Sie unter ASP.NET Core Blazor Komponente "QuickGrid".
ValidatableTypeAttribute und SkipValidationAttribute sind nicht mehr experimentell
Die Attribute SkipValidationAttribute und ValidatableTypeAttribute aus dem Microsoft.Extensions.Validation NuGet-Paket sind nicht mehr experimentell.
Weitere Informationen finden Sie in den folgenden Ressourcen:
Zwischenspeichern der gerenderten Ausgabe eines Komponenten-Teilbaums während statischer SSR
Die neue CacheView-Komponente zwischenspeichert die gerenderte Ausgabe eines Razor-Komponenten-Teilbaums beim statischen serverseitigen Rendern (static SSR). Bei einem Cache-Treffer wird das zwischengespeicherte Markup wiedergegeben, ohne die in der zwischengespeicherten Ausgabe enthaltenen untergeordneten Komponenten zu instanziieren oder deren Lebenszyklus auszuführen.
CacheView ist nützlich für ressourcenintensive, meist statische Abschnitte einer Seite, für die nicht die gesamte Antwort zwischengespeichert werden muss:
<CacheView VaryByQuery="category" ExpiresAfter="TimeSpan.FromMinutes(5)">
<ProductList Category="@Category" />
</CacheView>
Weitere Informationen finden Sie unter ASP.NET Core Blazor CacheView-Komponente.
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.
SignalR Authentifizierungsaktualisierung
SignalR Verbindungen können die Authentifizierung aktualisieren, ohne die Verbindung abzulegen, wenn das Zugriffstoken abläuft. Der Server stellt einen /refresh-Endpunkt zusammen mit /negotiate bereit und meldet in der Negotiate-Antwort die Tokengültigkeitsdauer. Der .NET Client erneut authentifiziert, bevor das Token abläuft, sodass eine Hubverbindung, die zuvor geschlossen wurde, wenn das Bearertoken abgelaufen ist, geöffnet bleiben kann. Diese Funktion ist für den .NET-Client implementiert; der JavaScript/TypeScript-Client und die Azure SignalR-Dienstunterstützung befinden sich in Arbeit.
Aktivieren Sie das Feature pro Hub auf dem Server:
app.MapHub<ChatHub>("/chat", options =>
{
options.EnableAuthenticationRefresh = true;
// Optional: decide whether a given connection can refresh.
options.OnAuthenticationRefresh = context => ValueTask.FromResult(true);
});
Ein Hub kann mit dem Überschreiben von OnAuthenticationRefreshedAsync auf eine aktualisierte Identität reagieren:
public class ChatHub : Hub
{
public override Task OnAuthenticationRefreshedAsync()
{
// The connection's User has been updated with the refreshed token.
return Task.CompletedTask;
}
}
Die automatische Aktualisierung ist im .NET-Client standardmäßig aktiviert und kann mit WithAuthenticationRefresh konfiguriert werden:
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/chat")
.WithAuthenticationRefresh(options =>
{
// EnableAutoRefresh is true by default.
options.RefreshBeforeExpiration = TimeSpan.FromMinutes(1);
options.OnAuthenticationRefreshed = context => Task.CompletedTask;
options.OnAuthenticationRefreshFailed = context => Task.CompletedTask;
})
.Build();
Hubaufrufe auf dem Client abbrechen
Der SignalR-Client kann einen regulären Aufruf einer Nicht-Streaming-Hubmethode abbrechen. Bisher konnten nur Streamingaufrufe vom Client abgebrochen werden. Wenn Sie nun ein CancellationToken an InvokeAsync übergeben und es abbrechen, sendet der Client eine Abbruchnachricht, und der CancellationToken-Parameter der Hubmethode wird auf dem Server ausgelöst.
// Client — canceling the token cancels the server-side invocation.
using var cts = new CancellationTokenSource();
var work = connection.InvokeAsync("LongRunningWork", cts.Token);
// ...
cts.Cancel();
// Hub — accept a CancellationToken to observe client cancellation.
public class WorkHub : Hub
{
public async Task LongRunningWork(CancellationToken cancellationToken)
{
await Task.Delay(TimeSpan.FromMinutes(5), cancellationToken);
}
}
SignalR.NET Client unterstützt die Authentifizierungsaktualisierung nach Umleitungen.
Der SignalR .NET-Client erweitert SignalR die Authentifizierungsaktualisierung, sodass sie funktioniert, wenn Sie Umleitungen an einen anderen Server aushandeln, der von @MoChilia beigetragen wurde. Diese Clientänderung ermöglicht die Unterstützung für die Umleitung von Servern wie Azure SignalR Dienst, die das Feature noch nicht aktiviert hat.
Der Client behält den App-Token-Provider über die Umleitung hinweg bei, übernimmt ein aktualisiertes Transport-Token aus der Antwort und behält tokenLifetimeSeconds bei, sodass die automatische Aktualisierung nach Ablauf des ursprünglichen Tokens weiterhin geplant bleibt.
Vielen Dank @MoChilia für diesen Beitrag!
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!
C#-Union-Typen
ASP.NET Core unterstützt C#-Union-Typen (C#-Sprachreferenz), die in .NET 11 neu sind, überall dort, wo System.Text.Json verwendet wird: JSON-Anforderungs- und Antworttextkörper in Minimal-APIs und MVC, SignalR-JsonHubProtocol, Blazor-JavaScript-Interoperabilität, persistenter Komponentenstatus und Parameter vorab gerenderter Komponenten.
public union UnionIntString(int, string);
app.MapGet("/value", () => new UnionIntString(42));
Unionstypen werden für Nicht-Textbindungsquellen wie Abfragezeichenfolgen, Routenwerte, Kopfzeilen und Formularfelder nicht unterstützt.
Für OpenAPI wird ein Endpunkt, der eine Union zurückgibt, mit einem anyOf Schema beschrieben, das jeden Falltyp auflistet. Im Gegensatz zu polymorphen Typen tragen Union-Fälle keinen Diskriminator $type, sodass jeder Fall wieder seine eigenständige Komponente (zum Beispiel #/components/schemas/Dog) anstelle einer duplizierten, mit Präfix versehenen Komponente verwendet. ApiExplorer erkennt eine Union anhand von JsonTypeInfoKind.Union, sodass das Schema auch an Swashbuckle und NSwag weitergegeben wird. Wenn mehrere Fälle zu derselben JSON-Form serialisiert werden, sind sie mit einem [JsonUnion] Klassifikator eindeutig zu unterscheiden.
SignalR Gewerkschaften erfordern das JSON-Hubprotokoll; MessagePack und Newtonsoft.Json Protokolle unterstützen keine Gewerkschaften.
Beispiele und zusätzliche Informationen, die für Blazor Apps gelten, finden Sie im Abschnitt "Komponentenparameter" im Abschnitt "Komponentenübersicht" und im Abschnitt "Pass-Parameter" des Artikels "Dynamisch gerenderte ASP.NET Core Razor Komponenten".
Asynchrone Überprüfung für minimale APIs
Minimale API-Überprüfung unterstützt jetzt asynchrone Validatoren end-to-End (dotnet/aspnetcore #66487, dotnet/aspnetcore #67183). Vorschau 5 lieferte die Bausteine für die asynchrone Formularprüfung in Blazor. Vorschau 6 fügt neue asynchrone DataAnnotations APIs in den Basisbibliotheken (AsyncValidationAttribute und IAsyncValidatableObject) hinzu und Microsoft.Extensions.Validation führt sie jetzt aus, wenn ein Endpunkt eine Anforderung überprüft.
Die einfachste Methode zum Hinzufügen einer asynchronen Regel ist ein benutzerdefiniertes Überprüfungsattribut. Leiten Sie von AsyncValidationAttribute ab und implementieren Sie IsValidAsync, um eine Datenbank abzufragen oder eine Remote-API aufzurufen, ohne einen Thread zu blockieren. Das synchrone IsValid ist ebenfalls abstrakt; lösen Sie von hier aus, wenn das Attribut nur asynchron überprüft wird:
using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.DependencyInjection;
public sealed class UniqueEmailAttribute : AsyncValidationAttribute
{
// Synchronous IsValid. This attribute validates asynchronously only.
protected override ValidationResult? IsValid(object? value, ValidationContext context) =>
throw new InvalidOperationException("Validate this attribute with IsValidAsync.");
protected override async Task<ValidationResult?> IsValidAsync(
object? value, ValidationContext context, CancellationToken cancellationToken)
{
var users = context.GetRequiredService<IUserService>();
if (value is string email && await users.EmailExistsAsync(email, cancellationToken))
{
return new ValidationResult("That email is already registered.");
}
return ValidationResult.Success;
}
}
Wenden Sie [UniqueEmail] wie jedes integrierte Validierungsattribut auf eine Eigenschaft an.
Für die Validierung, die sich über mehrere Eigenschaften oder das gesamte Objekt erstreckt, implementieren Sie IAsyncValidatableObject und geben Sie die Ergebnisse als IAsyncEnumerable<ValidationResult> zurück. Da IAsyncValidatableObjectIValidatableObject erweitert, implementieren Sie auch die synchrone Methode Validate. Wenn ein Typ nur asynchron validiert werden kann, lösen Sie von Validate aus, damit seine Validierung nicht von den synchronen APIs unbemerkt übersprungen wird:
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
public class ReservationRequest : IAsyncValidatableObject
{
[Required]
public string Email { get; set; } = "";
public DateOnly Date { get; set; }
// Synchronous IValidatableObject. This type validates asynchronously only.
public IEnumerable<ValidationResult> Validate(ValidationContext context) =>
throw new InvalidOperationException("Validate this type with ValidateAsync.");
public async IAsyncEnumerable<ValidationResult> ValidateAsync(
ValidationContext context,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var rooms = context.GetRequiredService<IRoomService>();
if (!await rooms.HasAvailabilityAsync(Date, cancellationToken))
{
yield return new ValidationResult(
"No rooms are available on that date.", [nameof(Date)]);
}
}
}
Registrieren Sie die Validierung, und das Framework validiert die Anfrage, bevor der Endpunkt ausgeführt wird:
builder.Services.AddValidation();
app.MapPost("/reservations", (ReservationRequest request) =>
Results.Ok(request));
Validierungssteuerelemente werden nach Möglichkeit parallel ausgeführt: Asynchrone Attribute für dasselbe Member werden gemeinsam gestartet, Sammlungselemente werden parallel validiert, und das Framework behält die vorhandene Reihenfolge zwischen Member-, Typ- und IValidatableObject-Validierung bei.
Kurzschlussendpunkte mit einem Attribut
Das neue [ShortCircuit] Attribut kennzeichnet einen Endpunkt, der unmittelbar nach dem Routing ausgeführt werden soll, wobei der Rest der Middleware-Pipeline übersprungen wird. Dies ist die Attributform der vorhandenen ShortCircuit() Endpunktkonvention, sodass sie direkt auf MVC-Controller und -Aktionen angewendet werden kann.
Das Kurzschließen ist für Endpunkte nützlich, die keine Authentifizierung, CORS oder andere Middleware benötigen, z. B. für einen Health Check oder eine robots.txt-Antwort, und dadurch entfallen die Kosten für die Ausführung dieser Middleware. Der Endpunkt läuft weiterhin und gibt eine Antwort zurück. Übergeben Sie einen optionalen Statuscode, wie [ShortCircuit(404)], um den Antwortstatuscode festzulegen.
[ApiController]
[Route("robots.txt")]
[ShortCircuit]
public class RobotsController : ControllerBase
{
[HttpGet]
public IActionResult Get() => Content("User-agent: *\nDisallow:", "text/plain");
}
Dasselbe Attribut funktioniert auf minimalen API-Endpunkten, und die vorhandene ShortCircuit() Konvention funktioniert weiterhin unverändert:
app.MapGet("/health", [ShortCircuit] () => "Healthy");
Vielen Dank @Porozhniakov, dass Sie zur Entwicklung dieses Features beigetragen haben!
Validierungslokalisierung ist integriert
Microsoft.Extensions.Validation lokalisiert Überprüfungsmeldungen und Anzeigenamen ohne separates Paket. Der Aufruf von AddLocalization zum Registrieren eines IStringLocalizerFactory, gefolgt von AddValidation, aktiviert die Lokalisierung automatisch. Der Validierungsquellengenerator gibt die Lokalisierungsabfrage in Ihre Assembly aus.
builder.Services.AddLocalization();
builder.Services.AddValidation();
[ValidatableType]
public class CustomerModel
{
[Display(Name = "CustomerName")] // resource key for the display name
[Required(ErrorMessage = "NameRequired")] // resource key for the message
public string? Name { get; set; }
}
Schlüssel werden anhand der modellinternen Ressourcen aufgelöst; bei einem Fehltreffer wird auf die integrierte Nachricht des Attributs zurückgegriffen. Verwenden Sie stattdessen ValidationOptions.LocalizerProvider, um Schlüssel aus einer freigegebenen Ressourcendatei aufzulösen:
builder.Services.AddValidation(options =>
{
options.LocalizerProvider = (_, factory) => factory.Create(typeof(ValidationMessages));
});
Attribute, die sich bereits selbst lokalisieren (ErrorMessageResourceType, [Display(ResourceType = ...)]), umgehen die Pipeline vollständig. Ein benutzerdefiniertes Attribut, das seine eigenen Werte in die Nachrichtenvorlage einsetzen muss, kann IValidationMessageFormatter implementieren:
public sealed class DivisibleByAttribute : ValidationAttribute, IValidationMessageFormatter
{
public int Divisor { get; init; }
public string FormatMessage(CultureInfo culture, string template, string displayName)
=> string.Format(culture, template, displayName, Divisor); // {0} = name, {1} = divisor
}
Die gleichen Lokalisierungsregeln gelten für die Überprüfung für minimale APIs und Blazor, sodass eine Nachricht identisch lokalisiert wird, wo das Modell verwendet wird.
Validierungsattribute sind nicht mehr experimentell.
ValidatableTypeAttribute und SkipValidationAttribute sind nicht mehr als experimentell gekennzeichnet. Wenn Sie ASP0029 unterdrückt haben, um eines der beiden Attribute zu verwenden, entfernen Sie die Unterdrückung.
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 Abfrage, 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!
OpenAPI 3.2 standardmäßig
Generierte OpenAPI-Dokumente zielen standardmäßig auf OpenAPI 3.2 ab. Dokumente werden weiterhin wie zuvor generiert. Legen Sie die Dokumentversion explizit fest, wenn Sie für Werkzeuge, die OpenAPI 3.2 noch nicht unterstützen, gezielt eine frühere Version verwenden müssen.
Wenn Sie eine frühere Version als Ziel festlegen möchten, geben Sie diese beim Aufrufen AddOpenApian:
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = Microsoft.OpenApi.OpenApiSpecVersion.OpenApi3_1;
});
Unterstützung für Server-Sent Events in OpenAPI 3.2
Endpunkte, die SseItem<T> zurückgeben, werden im generierten OpenAPI-Dokument mit der OpenAPI-3.2-Form itemSchema für text/event-stream-Antworten beschrieben. Das itemSchema beschreibt die Form der Nutzlast eines Datenstroms für jedes Ereignis, anstatt auf ein einfaches string-Schema zurückzugreifen.
app.MapGet("/todos/stream", (CancellationToken ct) =>
TypedResults.ServerSentEvents(GetTodosAsync(ct)))
.WithName("StreamTodos");
static async IAsyncEnumerable<SseItem<Todo>> GetTodosAsync(
[EnumeratorCancellation] CancellationToken ct = default)
{
foreach (var todo in Todos.All)
{
yield return new SseItem<Todo>(todo) { EventId = todo.Id.ToString() };
await Task.Delay(1000, ct);
}
}
Geben Sie den Datenstrom über TypedResults.ServerSentEvents zurück. Ein Handler, der IAsyncEnumerable<SseItem<T>> direkt zurückgibt, wird statt als SSE als JSON serialisiert. Verwenden Sie die spezielle SseItem<T>-Überladung ohne eventType. Um einen einzigen Ereignisnamen für den gesamten Stream zu verwenden, übergeben Sie ein einfaches IAsyncEnumerable<T> mit eventType.
Das generierte 3.2-Dokument beschreibt die Ereignisnutzlast, wobei itemSchema auf #/components/schemas/Todo verweist, sowie die standardmäßigen SSE-Zeichenfolgenfelder event und id:
responses:
'200':
description: OK
content:
text/event-stream:
itemSchema:
type: object
required: [data]
properties:
data:
$ref: '#/components/schemas/Todo'
event: { type: string }
id: { type: string }
Wenn die Ereignis-Payload eine diskriminierte Vereinigung ist (eine C# 14-Vorschau-Funktion), gibt OpenAPI auch die Fallnamen der Vereinigung als enum im event-Feld aus.
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.
dotnet user-jwts unterstützt dateibasierte Apps
Das dotnet user-jwts Tool erstellt signierte Entwicklungs-JWTs, sodass Sie die authentifizierten Endpunkte einer App aufrufen können, ohne einen echten Identitätsanbieter einzurichten. Der create Befehl generiert ein Token, speichert seinen Signaturschlüssel in den geheimen Benutzerschlüsseln der App und druckt das Token, das als Bearertoken verwendet werden soll. Sie funktioniert jetzt mit dateibasierten Apps (eine einzelne app.cs ohne Projektdatei) über die neue --file Option:
dotnet user-jwts create --file app.cs
Konsistente Autorisierungsmetadaten über den gesamten Stack hinweg
Autorisierungsmetadaten können als IAuthorizeData, ein AuthorizationPolicyoder ein IAuthorizationRequirementData Attribut ausgedrückt werden. MVC-Filter, SignalR-Hub-Methoden sowie AuthorizeView und AuthorizeRouteView von Blazor wenden alle drei Formen konsistent an.
Eine neue AuthorizationPolicy.CombineAsync-Überladung ist die gemeinsame Implementierung:
public class AuthorizationPolicy
{
public static Task<AuthorizationPolicy?> CombineAsync(
IAuthorizationPolicyProvider policyProvider,
IEnumerable<object> metadata);
}
MVC, SignalR und Blazor verwenden diese Überladung intern. Ein benutzerdefiniertes Attribut, das sowohl IAuthorizeData als auch IAuthorizationRequirementData implementiert, geht einmal in die Entscheidung ein. Der bisherige MVC-Pfad mit EnableEndpointRouting = false bleibt unverändert.
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.
Das Model Context Protocol (MCP) ist ein offener Standard, der KI-Anwendungen und -Agents, z. B. in Visual Studio, Visual Studio Code und GitHub Copilot, verwendet wird, um externe Tools, Daten und Dienste über eine konsistente Schnittstelle zu ermitteln und aufzurufen. Ein MCP-Server macht Ihre eigenen Funktionen verfügbar, z. B. benutzerdefinierte Tools oder Zugriff auf eine Datenquelle, sodass ein KI-Host sie im Namen des Benutzers aufrufen kann.
Verwenden Sie die mcpserver Vorlage, wenn Sie einen C#-MCP-Server erstellen möchten, der Ihren Code oder Ihre Dienste mit KI-basierten Tools integriert. Das generierte Projekt verwendet das offizielle C#SDK für MCP und enthält ein funktionierendes Beispieltool, sodass Sie einen runnablen Ausgangspunkt haben, um mit Ihren eigenen Tools zu erweitern.
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.
Weitere Informationen finden Sie unter Build a Model Context Protocol (MCP)-Server in C#.
Observability 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. Die Funktion funktioniert auch nach einem fehlgeschlagenen Handshake weiter – Kestrel erstellt eine Momentaufnahme der relevanten Felder des zugrunde liegenden SslStream, bevor sie freigegeben wird.
Die TlsClientHelloBytesCallback-Option auf HttpsConnectionAdapterOptions wurde zu einer Verbindungs-Middleware umgestaltet. Das vorherige Callback-Format ist nun veraltet. Konfigurieren Sie die ClientHello-Überprüfung 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 der Funktion 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 freigegebenen Frameworks als auch als eigenständige NuGet-Pakete ausgeliefert werden, sind hiervon ausgenommen, da „runtime-async“ nicht mit WebAssembly kompatibel ist und andernfalls Wasm-Verbraucher 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 Tokenfüllungen beim Zero-Permit-Erwerb falsch behandelte, und verbessern den von CreateChained zurückgegebenen verketteten Rate-Limiter, sodass Leerlaufdauer und Auffüllverhalten der 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 wendet jetzt RequestHeadersTimeout auf fragmentierte HTTP/2- und HTTP/3-Trailer-Header an, die die Übertragung des Header-Blocks nicht abschließen. Dieselbe Zeitüberschreitung, die die Header der ursprünglichen Anfrage schützt, verhindert jetzt auch, dass Verbindungen unbegrenzt offen bleiben, während Kestrel auf den Abschluss der Trailer-HEADERS-Frames wartet.
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
});
Zugriff auf TLS-Kanalbindungstoken von ITlsConnectionFeature
Anwendungen, die TLS verwenden, können das Kanalbindungstoken der Verbindung lesen, um sich gegen Relayangriffe zu schützen:
using System.Security.Authentication.ExtendedProtection;
app.Use(async (context, next) =>
{
var tls = context.Features.Get<ITlsConnectionFeature>();
if (tls is not null && tls.TryGetChannelBindingBytes(
ChannelBindingKind.Endpoint,
out ReadOnlyMemory<byte> cbt))
{
// Compare cbt against the token the client presented during authentication.
}
await next(context);
});
Kestrel gibt die Bindung aus SslStream.TransportContext.GetChannelBinding zurück. IIS und HTTP.sys geben sie aus der Anfrage zurück. Auf HTTP.sys steuert HttpSysOptions.HttpAuthenticationHardeningLevel den erweiterten Schutz und die Offenlegung von Kanalbindungstoken:
-
Legacydeaktiviert die Kanalbindungsüberprüfung und macht das Token nicht verfügbar. -
Medium, der Standardwert, stellt das Token bereit und überprüft es, wenn es übergeben wird, akzeptiert jedoch auch dessen Fehlen. -
Stricterfordert das Token für authentifizierte Anforderungen und lehnt Anforderungen ohne einen ab. Außerdem schlägt der Start fehl, wenn das Betriebssystem die Konfiguration nicht anwenden kann, währendLegacyundMediumden Konfigurationsfehler protokollieren und fortfahren.
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.