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.
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
In diesem Artikel wird erläutert, wie die Seitennavigation in Blazor ausgelöst und behandelt wird. Benutzer können zwar mithilfe normaler HTML-Links zwischen verschiedenen Seiten navigieren, die Navigation innerhalb der Anwendung wird jedoch verbessert, Blazor um vollständige Seitenladevorgänge zu vermeiden und eine reibungslosere Benutzererfahrung zu erzielen. Verwenden Sie die NavLink Komponente, um Navigationslinks zu erstellen, die automatisch Formatierungen anwenden, wenn der Link mit der aktuellen Seite übereinstimmt. Verwenden Sie für die programmgesteuerte Navigation und die URI-Verwaltung im C#-Code den NavigationManager Dienst.
In diesem Artikel wird erläutert, wie die Seitennavigation in Blazor ausgelöst und behandelt wird. Verwenden Sie die NavLink Komponente, um Navigationslinks zu erstellen, die automatisch Formatierungen anwenden, wenn der Link mit der aktuellen Seite übereinstimmt. Verwenden Sie für die programmgesteuerte Navigation und die URI-Verwaltung im C#-Code den NavigationManager Dienst.
Von Bedeutung
Die Codebeispiele in diesem Artikel zeigen Methoden, die für Navigation aufgerufen werden, einen in Klassen und Komponenten injizierten NavigationManager.
NavLink-Komponente
Verwenden Sie bei der Erstellung von Navigationslinks eine NavLink-Komponente anstelle von HTML-Hyperlinkelementen (<a>). Eine NavLink-Komponente verhält sich wie ein <a>-Element, abgesehen davon, dass sie eine active-CSS-Klasse umschaltet, je nachdem, ob das href-Element mit der aktuellen URL übereinstimmt. Die active-Klasse zeigt einem Benutzer auf, welche Seite unter den angezeigten Navigationslinks aktiv ist. Optional können Sie NavLink.ActiveClass einen CSS-Klassennamen zuweisen, um eine benutzerdefinierte CSS-Klasse auf den gerenderten Link anzuwenden, wenn die aktuelle Route mit href übereinstimmt.
In der NavMenu Komponente (NavMenu.razor) einer Blazor-App, die aus einer Blazor-Projektvorlage erstellt wurde:
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
Im vorherigen Beispiel entspricht HomeNavLinkhref="" der Home-URL und empfängt nur die CSS-Klasse active im Standardbasispfad der App (/). Die zweite NavLink erhält die active Klasse, wenn der Benutzer die Counter Komponente an /counter besucht.
Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:
-
NavLinkMatch.All: Die NavLink ist aktiv, wenn sie mit der aktuellen URL übereinstimmt, wobei die Abfragezeichenfolge und das Fragment ignoriert werden. Um eine Übereinstimmung in der Abfragezeichenfolge oder im Fragment zu ermöglichen, verwenden Sie den
Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragmentAppContextSchalter, der auftruegesetzt ist. - NavLinkMatch.Prefix (Standardwert): NavLink ist aktiv, wenn ein Präfix mit der aktuellen URL übereinstimmt.
Um benutzerdefinierte Zuordnungslogik zu übernehmen, muss eine Unterklasse von NavLink erstellt und deren Methode ShouldMatch überschrieben werden. Geben Sie true aus der Methode zurück, wenn Sie die active CSS-Klasse anwenden möchten:
public class CustomNavLink : NavLink
{
protected override bool ShouldMatch(string currentUriAbsolute)
{
// Custom matching logic
}
}
Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:
- NavLinkMatch.All: Die NavLink ist aktiv, wenn sie mit der gesamten aktuellen URL übereinstimmt, einschließlich der Abfragezeichenfolge und des Fragments.
- NavLinkMatch.Prefix (Standardwert): NavLink ist aktiv, wenn ein Präfix mit der aktuellen URL übereinstimmt.
Zusätzliche NavLink-Komponentenattribute werden an das gerenderte Ankertag weitergegeben. Im folgenden Beispiel schließt die NavLink-Komponente das target-Attribut ein:
<NavLink href="example-page" target="_blank">Example page</NavLink>
Das folgende HTML-Markup wird gerendert:
<a href="example-page" target="_blank">Example page</a>
Warnung
Aufgrund der Art und Weise, in der Blazor untergeordneten Inhalt rendert, erfordert das Rendern von NavLink-Komponenten in einer for-Schleife eine lokale Indexvariable, wenn die inkrementierende Schleifenvariable im Inhalt der untergeordneten Komponente (NavLink) verwendet wird:
@for (int c = 1; c < 4; c++)
{
var ct = c;
<li ...>
<NavLink ...>
<span ...></span> Product #@ct
</NavLink>
</li>
}
Die Verwendung einer Indexvariable in diesem Szenario ist eine Anforderung für jede untergeordnete Komponente, die eine Schleifenvariable im untergeordneten Inhalt verwendet, nicht nur für die NavLink-Komponente.
Alternativ dazu können Sie eine foreach-Schleife mit Enumerable.Range verwenden:
@foreach (var c in Enumerable.Range(1, 3))
{
<li ...>
<NavLink ...>
<span ...></span> Product #@c
</NavLink>
</li>
}
Hilfsprogramme für URI und Navigationszustand
Verwenden Sie NavigationManager, um URIs und die Navigation im C#-Code zu verwalten. NavigationManager stellt das Ereignis und die Methoden bereit, die in der folgenden Tabelle aufgeführt sind.
| Mitglied | Description |
|---|---|
| Uri | Ruft den aktuellen absoluten URI ab. |
| BaseUri | Ruft den Basis-URI (mit einem nachgestellten Schrägstrich) ab, der relativen URI-Pfaden vorangestellt werden kann, um einen absoluten URI zu erhalten. In der Regel entspricht BaseUri dem Attribut href im Element <base> des Dokuments (Speicherort des <head>-Inhalts). |
| NavigateTo | Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert false:
forceLoad lautet der Wert true:
Weitere Informationen finden Sie im Abschnitt Erweiterte Navigation und Formularverarbeitung. Wenn |
| LocationChanged | Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat. Weitere Informationen finden Sie im Abschnitt Positionsänderungen. |
NotFound |
Wird aufgerufen, um Szenarien zu behandeln, in denen eine angeforderte Ressource nicht gefunden wird. Weitere Informationen finden Sie im Abschnitt " Nicht gefundene Antworten ". |
| ToAbsoluteUri | Konvertiert einen relativen URI in einen absoluten URI. |
| ToBaseRelativePath | Konvertiert auf der Grundlage des Basis-URI der App einen absoluten URI in einen URI relativ zum Präfix des Basis-URI. Ein Beispiel finden Sie im Abschnitt Erzeugen eines URI relativ zum Basis-URI-Präfix. |
RegisterLocationChangingHandler |
Registriert einen Handler zum Verarbeiten eingehender Navigationsereignisse. Beim Aufrufen von NavigateTo wird immer der Handler aufgerufen. |
| GetUriWithQueryParameter | Gibt einen URI zurück, der durch Aktualisieren von NavigationManager.Uri erstellt wird, wobei ein einzelner Parameter hinzugefügt, aktualisiert oder entfernt wurde. Weitere Informationen finden Sie im Abschnitt Abfragezeichenfolgen. |
| Mitglied | Description |
|---|---|
| Uri | Ruft den aktuellen absoluten URI ab. |
| BaseUri | Ruft den Basis-URI (mit einem nachgestellten Schrägstrich) ab, der relativen URI-Pfaden vorangestellt werden kann, um einen absoluten URI zu erhalten. In der Regel entspricht BaseUri dem Attribut href im Element <base> des Dokuments (Speicherort des <head>-Inhalts). |
| NavigateTo | Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert false:
forceLoad lautet der Wert true:
Weitere Informationen finden Sie im Abschnitt Erweiterte Navigation und Formularverarbeitung. Wenn |
| LocationChanged | Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat. Weitere Informationen finden Sie im Abschnitt Positionsänderungen. |
| ToAbsoluteUri | Konvertiert einen relativen URI in einen absoluten URI. |
| ToBaseRelativePath | Konvertiert auf der Grundlage des Basis-URI der App einen absoluten URI in einen URI relativ zum Präfix des Basis-URI. Ein Beispiel finden Sie im Abschnitt Erzeugen eines URI relativ zum Basis-URI-Präfix. |
RegisterLocationChangingHandler |
Registriert einen Handler zum Verarbeiten eingehender Navigationsereignisse. Beim Aufrufen von NavigateTo wird immer der Handler aufgerufen. |
| GetUriWithQueryParameter | Gibt einen URI zurück, der durch Aktualisieren von NavigationManager.Uri erstellt wird, wobei ein einzelner Parameter hinzugefügt, aktualisiert oder entfernt wurde. Weitere Informationen finden Sie im Abschnitt Abfragezeichenfolgen. |
| Mitglied | Description |
|---|---|
| Uri | Ruft den aktuellen absoluten URI ab. |
| BaseUri | Ruft den Basis-URI (mit einem nachgestellten Schrägstrich) ab, der relativen URI-Pfaden vorangestellt werden kann, um einen absoluten URI zu erhalten. In der Regel entspricht BaseUri dem Attribut href im Element <base> des Dokuments (Speicherort des <head>-Inhalts). |
| NavigateTo | Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert true:
replace den Wert true hat, wird der aktuelle URI im Browserverlauf ersetzt, anstatt einen neuen URI auf den Verlaufsstapel zu pushen. |
| LocationChanged | Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat. Weitere Informationen finden Sie im Abschnitt Positionsänderungen. |
| ToAbsoluteUri | Konvertiert einen relativen URI in einen absoluten URI. |
| ToBaseRelativePath | Konvertiert auf der Grundlage des Basis-URI der App einen absoluten URI in einen URI relativ zum Präfix des Basis-URI. Ein Beispiel finden Sie im Abschnitt Erzeugen eines URI relativ zum Basis-URI-Präfix. |
RegisterLocationChangingHandler |
Registriert einen Handler zum Verarbeiten eingehender Navigationsereignisse. Beim Aufrufen von NavigateTo wird immer der Handler aufgerufen. |
| GetUriWithQueryParameter | Gibt einen URI zurück, der durch Aktualisieren von NavigationManager.Uri erstellt wird, wobei ein einzelner Parameter hinzugefügt, aktualisiert oder entfernt wurde. Weitere Informationen finden Sie im Abschnitt Abfragezeichenfolgen. |
| Mitglied | Description |
|---|---|
| Uri | Ruft den aktuellen absoluten URI ab. |
| BaseUri | Ruft den Basis-URI (mit einem nachgestellten Schrägstrich) ab, der relativen URI-Pfaden vorangestellt werden kann, um einen absoluten URI zu erhalten. In der Regel entspricht BaseUri dem Attribut href im Element <base> des Dokuments (Speicherort des <head>-Inhalts). |
| NavigateTo | Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert true:
replace den Wert true hat, wird der aktuelle URI im Browserverlauf ersetzt, anstatt einen neuen URI auf den Verlaufsstapel zu pushen. |
| LocationChanged | Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat. Weitere Informationen finden Sie im Abschnitt Positionsänderungen. |
| ToAbsoluteUri | Konvertiert einen relativen URI in einen absoluten URI. |
| ToBaseRelativePath | Konvertiert auf der Grundlage des Basis-URI der App einen absoluten URI in einen URI relativ zum Präfix des Basis-URI. Ein Beispiel finden Sie im Abschnitt Erzeugen eines URI relativ zum Basis-URI-Präfix. |
| GetUriWithQueryParameter | Gibt einen URI zurück, der durch Aktualisieren von NavigationManager.Uri erstellt wird, wobei ein einzelner Parameter hinzugefügt, aktualisiert oder entfernt wurde. Weitere Informationen finden Sie im Abschnitt Abfragezeichenfolgen. |
| Mitglied | Description |
|---|---|
| Uri | Ruft den aktuellen absoluten URI ab. |
| BaseUri | Ruft den Basis-URI (mit einem nachgestellten Schrägstrich) ab, der relativen URI-Pfaden vorangestellt werden kann, um einen absoluten URI zu erhalten. In der Regel entspricht BaseUri dem Attribut href im Element <base> des Dokuments (Speicherort des <head>-Inhalts). |
| NavigateTo | Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert true:
|
| LocationChanged | Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat. |
| ToAbsoluteUri | Konvertiert einen relativen URI in einen absoluten URI. |
| ToBaseRelativePath | Konvertiert auf der Grundlage des Basis-URI der App einen absoluten URI in einen URI relativ zum Präfix des Basis-URI. Ein Beispiel finden Sie im Abschnitt Erzeugen eines URI relativ zum Basis-URI-Präfix. |
Standortänderungen
Für das LocationChanged-Ereignis bietet LocationChangedEventArgs die folgenden Informationen zu Navigationsereignissen:
- Location: Die URL des neuen Speicherorts.
-
IsNavigationIntercepted: Wenn der Wert
trueist, hat Blazor die Navigation vom Browser abgefangen. Wenn der Wertfalseist, hat NavigationManager.NavigateTo bewirkt, dass die Navigation erfolgt ist.
Die folgende -Komponente:
- Sie navigiert zur
Counter-Komponente der App (Counter.razor), wenn die Schaltfläche mit NavigateTo geklickt wird. - Sie reagiert auf das „Location Changed“-Ereignis, indem sie NavigationManager.LocationChanged abonniert.
Die Einbindung der
HandleLocationChanged-Methode wird aufgehoben, wennDisposevom Framework aufgerufen wird. Durch das Aufheben der Einbindung der Methode wird die Garbage Collection für die Komponente ermöglicht.Die Protokollierungsimplementierung protokolliert die folgenden Informationen, wenn die Schaltfläche geklickt wird:
BlazorSample.Pages.Navigate: Information: URL of new location: https://localhost:{PORT}/counter
Navigate.razor:
@page "/navigate"
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation
<h1>Navigate Example</h1>
<button class="btn btn-primary" @onclick="NavigateToCounterComponent">
Navigate to the Counter component
</button>
@code {
private void NavigateToCounterComponent() => Navigation.NavigateTo("counter");
protected override void OnInitialized() =>
Navigation.LocationChanged += HandleLocationChanged;
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) =>
Logger.LogInformation("URL of new location: {Location}", e.Location);
public void Dispose() => Navigation.LocationChanged -= HandleLocationChanged;
}
Weitere Informationen zur Entsorgung von Komponenten finden Sie unter ASP.NET Core Razor Komponentenentsorgung.
Navigations-Manager-Umleitungsverhalten während des statischen serverseitigen Renderings (statischer SSR)
Bei einer Umleitung während des statischen serverseitigen Renderings (statischer SSR) NavigationManager wird ein Vom Framework erfasstes, NavigationException das den Fehler in eine Umleitung konvertiert. Code, der nach dem Aufruf NavigateTo vorhanden ist, wird nicht aufgerufen. Bei Verwendung von Visual Studio wird der Debugger für die Ausnahme unterbrochen, sodass Sie das Kontrollkästchen für "Unterbrechen" deaktivieren müssen , wenn dieser Ausnahmetyp in der Visual Studio-Benutzeroberfläche vom Benutzer behandelt wird , um zu vermeiden, dass der Debugger für zukünftige Umleitungen beendet wird.
Sie können die <BlazorDisableThrowNavigationException> MSBuild-Eigenschaft verwenden, true die in der Projektdatei der App festgelegt ist, um die Anmeldung nicht mehr auszuwerfen NavigationException. Außerdem code after the call to NavigateTo executes when it wouldn't have run before. Dieses Verhalten ist in der .NET 10- oder höher-Projektvorlage Blazor Web App standardmäßig aktiviert:
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
Hinweis
In .NET 10 oder höher können Sie sich dafür entscheiden, einen NavigationException Fehler nicht auszuwerfen, indem Sie die <BlazorDisableThrowNavigationException> MSBuild-Eigenschaft true in der Projektdatei der App festlegen. Um die neue MSBuild-Eigenschaft und das neue Verhalten zu nutzen, aktualisieren Sie die App auf .NET 10 oder höher.
Nicht gefundene Antworten
NavigationManager bietet eine NotFound Methode zum Behandeln von Szenarien, in denen eine angeforderte Ressource während des statischen serverseitigen Renderings (statischer SSR) oder des globalen interaktiven Renderings nicht gefunden wird:
Statischer SSR: Durch Aufrufen
NavigationManager.NotFoundwird der HTTP-Statuscode auf 404 festgelegt.Interaktives Rendering: Signalisiert den Blazor Router (
RouterKomponente), um nicht gefundenen Inhalt zu rendern.Streamingrendering: Wenn die erweiterte Navigation aktiv ist, rendert das Streamingrendering nicht gefundenen Inhalt, ohne die Seite neu zu laden. Wenn die erweiterte Navigation blockiert wird, leitet das Framework mit einer Seitenaktualisierung zu nicht gefundenem Inhalt um.
Hinweis
In der folgenden Diskussion wird erwähnt, dass eine Nicht gefundene Razor Komponente dem Parameter der Router Komponente NotFoundPage zugewiesen werden kann. Der Parameter arbeitet in Abstimmung mit NavigationManager.NotFound und wird weiter unten in diesem Abschnitt ausführlicher beschrieben.
Das Streaming-Rendering kann nur Komponenten rendern, die über eine Route verfügen, wie zum Beispiel eine NotFoundPage-Zuordnung (NotFoundPage="...") oder eine -Zuordnung der Middleware für die Neuausführung von Statuscodeseiten (UseStatusCodePagesWithReExecute).
DefaultNotFound 404 Inhalt ("Not foundPlaintext") verfügt nicht über eine Route, sodass er während des Streaming-Rendering nicht verwendet werden kann.
Hinweis
Das Nicht gefundene Renderfragment (<NotFound>...</NotFound>) wird in .NET 10 oder höher nicht unterstützt.
NavigationManager.NotFound Das Rendern von Inhalten verwendet Folgendes, unabhängig davon, ob die Antwort gestartet wurde oder nicht (in der Reihenfolge):
- Wenn NotFoundEventArgs.Path festgelegt ist, rendern Sie den Inhalt der angegebenen Seite.
- Wenn
Router.NotFoundPagefestgelegt ist, rendern Sie die zugewiesene Seite. - Eine Middleware-Seite für die Wiederholungsausführung von Statuscode-Seiten, falls konfiguriert.
- Keine Aktion, wenn keine der vorherigen Ansätze angenommen wird.
StatusCode-Pages-Re-execution-Middleware mit UseStatusCodePagesWithReExecute priorisiert browserbedingte Routing-Probleme, wie beispielsweise einer falsch eingegebenen URL in der Adressleiste des Browsers oder bei einem Klick auf einen Link, der in der App keinen Endpunkt hat.
Wenn eine Komponente statisch gerendert wird (statischeR SSR) und NavigationManager.NotFound aufgerufen wird, wird der Statuscode 404 für die Antwort festgelegt:
@page "/render-not-found-ssr"
@inject NavigationManager Navigation
@code {
protected override void OnInitialized()
{
Navigation.NotFound();
}
}
Um nicht gefundenen Inhalt für das globale interaktive Rendering bereitzustellen, verwenden Sie eine Nicht gefundene Seite (Razor Komponente).
Hinweis
Die Blazor Projektvorlage enthält eine NotFound.razor Seite. Diese Seite wird bei jedem NavigationManager.NotFound Aufruf automatisch gerendert, sodass fehlende Routen mit einer konsistenten Benutzeroberfläche verarbeitet werden können.
Pages/NotFound.razor:
@page "/not-found"
@layout MainLayout
<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>
Die NotFound Komponente wird dem Parameter des Routers NotFoundPage zugewiesen.
NotFoundPage unterstützt Routing, das für Statuscodeseiten für die erneute Ausführung von Middleware verwendet werden kann, einschließlich solcher, die ohneBlazor Middleware ausgeführt werden.
Im folgenden Beispiel ist die vorangehende NotFound Komponente im Ordner der App Pages vorhanden und an den NotFoundPage Parameter übergeben:
<Router AppAssembly="@typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="@routeData" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
Wenn eine Komponente mit einem globalen interaktiven Rendermodus gerendert wird, signalisiert das Aufrufen von NavigationManager.NotFound dem Blazor Router, die NotFound Komponente zu rendern.
@page "/render-not-found-interactive"
@inject NavigationManager Navigation
@if (RendererInfo.IsInteractive)
{
<button @onclick="TriggerNotFound">Trigger Not Found</button>
}
@code {
private void TriggerNotFound()
{
Navigation.NotFound();
}
}
Sie können das OnNotFound-Ereignis für Benachrichtigungen verwenden, wenn NavigationManager.NotFound aufgerufen wird. Das Ereignis wird nur ausgelöst, wenn NavigationManager.NotFound aufgerufen wird, nicht bei einer 404-Antwort. Beispielsweise löst die Einstellung HttpContextAccessor.HttpContext.Response.StatusCode auf 404NavigationManager.NotFound/OnNotFound nicht aus.
Apps, die einen benutzerdefinierten Router implementieren, können auch NavigationManager.NotFound verwenden. Der benutzerdefinierte Router kann nicht gefundene Inhalte aus zwei Quellen rendern, abhängig vom Status der Antwort:
Unabhängig vom Antwortzustand kann der Ausführungspfad erneut zur Seite verwendet werden, indem er an UseStatusCodePagesWithReExecute übergeben wird.
app.UseStatusCodePagesWithReExecute( "/not-found", createScopeForStatusCodePages: true);Wenn die Antwort gestartet wurde, kann das NotFoundEventArgs.Path verwendet werden, indem man den
OnNotFoundEventim Router abonniert:@code { [CascadingParameter] public HttpContext? HttpContext { get; set; } private void OnNotFoundEvent(object sender, NotFoundEventArgs e) { // Only execute the logic if HTTP response has started, // because setting NotFoundEventArgs.Path blocks re-execution if (HttpContext?.Response.HasStarted == false) { return; } var type = typeof(CustomNotFoundPage); var routeAttributes = type.GetCustomAttributes<RouteAttribute>(inherit: true); if (routeAttributes.Length == 0) { throw new InvalidOperationException($"The type {type.FullName} " + $"doesn't have a {nameof(RouteAttribute)} applied."); } var routeAttribute = (RouteAttribute)routeAttributes[0]; if (routeAttribute.Template != null) { e.Path = routeAttribute.Template; } } }
Im folgenden Beispiel für Komponenten, die interaktives serverseitiges Rendering (interaktive sSR) übernehmen, wird benutzerdefinierter Inhalt je nach Aufruf OnNotFound gerendert. Wenn das Ereignis von der folgenden Movie Komponente ausgelöst wird, wenn ein Film bei der Komponenteninitialisierung nicht gefunden wird, gibt eine benutzerdefinierte Meldung an, dass der angeforderte Film nicht gefunden wird. Wenn das Ereignis von der User Komponente im folgenden Beispiel ausgelöst wird, gibt eine andere Meldung an, dass der Benutzer nicht gefunden wird.
Der folgende NotFoundContext Dienst verwaltet den Kontext und die Meldung, wann Inhalte nicht von Komponenten gefunden werden.
NotFoundContext.cs:
public class NotFoundContext
{
public string? Heading { get; private set; }
public string? Message { get; private set; }
public void UpdateContext(string heading, string message)
{
Heading = heading;
Message = message;
}
}
Der Dienst wird in der serverseitigen Program Datei registriert:
builder.Services.AddScoped<NotFoundContext>();
Die NotFound Seite injiziert NotFoundContext und zeigt die Überschrift und Nachricht an.
Pages/NotFound.razor:
@page "/not-found"
@layout MainLayout
@inject NotFoundContext NotFoundContext
<h3>@NotFoundContext.Heading</h3>
<div>
<p>@NotFoundContext.Message</p>
</div>
Die Routes Komponente (Routes.razor) legt die NotFound Komponente als die Seite "Nicht gefunden" über den NotFoundPage Parameter fest:
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
...
</Router>
In den folgenden Beispielkomponenten:
- Der
NotFoundContext-Dienst wird zusammen mit dem NavigationManager-Dienst eingefügt. - In OnInitializedAsync,
HandleNotFoundist ein Ereignishandler, der demOnNotFoundEreignis zugewiesen ist.HandleNotFoundruftNotFoundContext.UpdateContextauf, um eine Überschrift und eine Nachricht für Nicht gefunden-Inhalt in derNotFoundKomponente festzulegen. - Die Komponenten würden normalerweise eine ID aus einem Routenparameter verwenden, um einen Film oder Benutzer aus einem Datenspeicher wie z. B. einer Datenbank abzurufen. In den folgenden Beispielen wird keine Entität zurückgegeben (
null), um zu simulieren, was passiert, wenn eine Entität nicht gefunden wird. - Wenn keine Entität an OnInitializedAsync zurückgegeben wird, wird
NavigationManager.NotFoundaufgerufen, was wiederum dasOnNotFoundEreignis und denHandleNotFoundEreignishandler auslöst. Der "Nicht gefunden"-Inhalt wird vom Router angezeigt. - Die
HandleNotFoundMethode wird in IDisposable.Dispose bei der Entsorgung von Komponenten entkoppelt.
Movie-KomponenteMovie.razor
@page "/movie/{Id:int}"
@implements IDisposable
@inject NavigationManager NavigationManager
@inject NotFoundContext NotFoundContext
<div>
No matter what ID is used, no matching movie is returned
from the call to GetMovie().
</div>
@code {
[Parameter]
public int Id { get; set; }
protected override async Task OnInitializedAsync()
{
NavigationManager.OnNotFound += HandleNotFound;
var movie = await GetMovie(Id);
if (movie == null)
{
NavigationManager.NotFound();
}
}
private void HandleNotFound(object? sender, NotFoundEventArgs e)
{
NotFoundContext.UpdateContext("Movie Not Found",
"Sorry! The requested movie wasn't found.");
}
private async Task<MovieItem[]?> GetMovie(int id)
{
// Simulate no movie with matching id found
return await Task.FromResult<MovieItem[]?>(null);
}
void IDisposable.Dispose()
{
NavigationManager.OnNotFound -= HandleNotFound;
}
public class MovieItem
{
public int Id { get; set; }
public string? Title { get; set; }
}
}
User-KomponenteUser.razor
@page "/user/{Id:int}"
@implements IDisposable
@inject NavigationManager NavigationManager
@inject NotFoundContext NotFoundContext
<div>
No matter what ID is used, no matching user is returned
from the call to GetUser().
</div>
@code {
[Parameter]
public int Id { get; set; }
protected override async Task OnInitializedAsync()
{
NavigationManager.OnNotFound += HandleNotFound;
var user = await GetUser(Id);
if (user == null)
{
NavigationManager.NotFound();
}
}
private void HandleNotFound(object? sender, NotFoundEventArgs e)
{
NotFoundContext.UpdateContext("User Not Found",
"Sorry! The requested user wasn't found.");
}
private async Task<UserItem[]?> GetUser(int id)
{
// Simulate no user with matching id found
return await Task.FromResult<UserItem[]?>(null);
}
void IDisposable.Dispose()
{
NavigationManager.OnNotFound -= HandleNotFound;
}
public class UserItem
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Um die vorherigen Komponenten in einer lokalen Demonstration mit einer Test-App zu erreichen, erstellen Sie Einträge in der NavMenu Komponente (NavMenu.razor), um die Movie Komponenten und User Komponenten zu erreichen. Die Entitäts-IDs, die als Routenparameter übergeben werden, sind im folgenden Beispiel simulierte Werte, die keine Auswirkungen haben, da sie nicht tatsächlich von den Komponenten verwendet werden, die simulieren, dass kein Film oder Benutzer gefunden wird.
In NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="movie/1">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Movie
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="user/2">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User
</NavLink>
</div>
Erweiterte Navigations- und Formularverarbeitung
Dieser Abschnitt gilt für Blazor Web Apps.
Blazor Web App-Komponenten können zwei Arten von Routing für Anforderungen zur Seitennavigation und zur Formularverarbeitung nutzen:
- Normale Navigation (dokumentübergreifende Navigation): Für die Anforderungs-URL wird ein Neuladen der ganzen Seite ausgelöst.
- Erweiterte Navigation (Navigation innerhalb desselben Dokuments): Blazor fängt die Anforderung ab und führt stattdessen eine
fetch-Anfrage aus. Blazor fügt den Antwortinhalt in das DOM der Seite ein. Durch die erweiterte Navigation und Formularverarbeitung von Blazor wird vermieden, dass ein Neuladen der ganzen Seite erforderlich ist. Zudem wird der Seitenzustand beibehalten, sodass Seiten schneller geladen werden – normalerweise sogar, ohne die Scrollposition des Benutzers oder der Benutzerin auf der Seite zu verlieren.
Die erweiterte Navigation ist verfügbar, wenn:
- Das Blazor Web App-Skript (
blazor.web.js) wird verwendet, nicht das Blazor Server- Skript (blazor.server.js) oder Blazor WebAssembly-Skript (blazor.webassembly.js). - Das Feature ist nicht explizit deaktiviert.
- Die Ziel-URL befindet sich innerhalb des internen Basis-URI-Raums (Basispfad der App), und der Link zu der Seite hat das Attribut
data-enhance-navnicht auffalsegesetzt.
Wenn serverseitiges Routing und erweiterte Navigation aktiviert sind, werden Positionsänderungshandler nur für die programmgesteuerte Navigation aufgerufen, die von einer interaktiven Runtime initiiert werden. In zukünftigen Releases können zusätzliche Navigationstypen, z. B. Linkklicks, auch Positionsänderungshandler aufrufen.
Bei einer erweiterten Navigation werden in der Regel LocationChanged-Ereignishandler aufgerufen, die bei interaktiven Server- und WebAssembly-Runtimes registriert sind. Es gibt Fälle, in denen Positionsänderungshandler möglicherweise keine erweiterte Navigation abfangen. Beispielsweise könnte ein*e Benutzer*in zu einer anderen Seite wechseln, bevor eine interaktive Runtime verfügbar ist. Daher ist es wichtig, dass die App-Logik nicht auf einen Handler zum Ändern der Position angewiesen ist, da keine Garantie für die Ausführung des Handlers besteht.
Beim Aufruf von NavigateTo:
- Wenn
forceLoadden Wertfalseaufweist (Standardwert):- Die erweiterte Navigation ist unter der aktuellen URL verfügbar, und die erweiterte Blazor-Navigation ist aktiviert.
- Andernfalls lädt Blazor die Seite für die angeforderte URL vollständig neu.
- Wenn
forceLoadden Werttrueaufweist: Blazor lädt die Seite für die angeforderte URL vollständig neu, unabhängig davon, ob die erweiterte Navigation verfügbar ist oder nicht.
Sie können die aktuelle Seite aktualisieren, indem Sie NavigationManager.Refresh(bool forceLoad = false)aufrufen, wodurch bei Bedarf immer eine erweiterte Navigation angewendet wird. Wenn die erweiterte Navigation nicht verfügbar ist, lädt Blazor die ganze Seite neu.
Navigation.Refresh();
Übergeben Sie true an den Parameter forceLoad, damit immer die ganze Seite neu geladen wird, auch wenn die erweiterte Navigation verfügbar ist:
Navigation.Refresh(true);
Die erweiterte Navigation ist standardmäßig aktiviert, kann jedoch mithilfe des HTML-Attributs data-enhance-nav hierarchisch und pro Link gesteuert werden.
In den folgenden Beispielen wird die erweiterte Navigation deaktiviert:
<a href="redirect" data-enhance-nav="false">
GET without enhanced navigation
</a>
<ul data-enhance-nav="false">
<li>
<a href="redirect">GET without enhanced navigation</a>
</li>
<li>
<a href="redirect-2">GET without enhanced navigation</a>
</li>
</ul>
Wenn es sich bei dem Ziel um einen Nicht-Blazor-Endpunkt handelt, wird die erweiterte Navigation nicht angewendet, und die Seite wird clientseitig mit JavaScript vollständig neu geladen. Dadurch wird sichergestellt, dass im Framework keine Verwirrung über externe Seiten entsteht, die nicht in eine vorhandene Seite gepatcht werden sollten.
Um die erweiterte Formularverarbeitung zu aktivieren, fügen Sie den Enhance-Parameter zu EditForm-Formularen oder das data-enhance-Attribut zu HTML-Formularen (<form>) hinzu:
<EditForm ... Enhance ...>
...
</EditForm>
<form ... data-enhance ...>
...
</form>
Die erweiterte Formularverarbeitung ist nicht hierarchisch und wird nicht an untergeordnete Formulare übergeben:
Nicht unterstützt: Sie können die erweiterte Navigation im Vorgängerelement eines Formulars nicht festlegen, um die erweiterte Navigation für das Formular zu aktivieren.
<div ... data-enhance ...>
<form ...>
<!-- NOT enhanced -->
</form>
</div>
Erweiterte Formularbeiträge funktionieren nur mit Blazor-Endpunkten. Das Bereitstellen eines erweiterten Formulars an einen Nicht-Blazor-Endpunkt führt zu einem Fehler.
So deaktivieren Sie die erweiterte Navigation:
- Entfernen Sie für ein EditForm-Formular den Parameter Enhance aus dem Formularelement (oder legen Sie diesen auf
falsefest:Enhance="false"). - Entfernen Sie für einen
<form>-HTML-Element den Parameterdata-enhanceaus dem Formularelement (oder legen Sie diesen auffalsefest:data-enhance="false").
Die erweiterte Navigation und Formularverarbeitung von Blazor können dynamische Änderungen am Dokumentobjektmodell (DOM) rückgängig machen, wenn der aktualisierte Inhalt nicht Teil des Serverrenderings ist. Verwenden Sie das data-permanent-Attribut, um den Inhalt eines Elements beizubehalten.
Im folgenden Beispiel wird der Inhalt des <div>-Elements dynamisch durch ein Skript aktualisiert, wenn die Seite geladen wird:
<div data-permanent>
...
</div>
Sobald Blazor den Client gestartet hat, können Sie das enhancedload-Ereignis verwenden, um nach erweiterten Seitenaktualisierungen zu lauschen. Das ermöglicht es, Änderungen, die möglicherweise durch ein verbessertes Seitenupdate rückgängig gemacht wurden, erneut auf das Dokumentobjektmodell (DOM) anzuwenden.
Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));
Informationen zum globalen Deaktivieren der erweiterten Navigation und Formularverarbeitung finden Sie unter ASP.NET Core Blazor-Start.
Die erweiterte Navigation mit statischem serverseitigem Rendering (statisches SSR) erfordert besondere Aufmerksamkeit beim Laden von JavaScript. Weitere Informationen finden Sie unter ASP.NET Core Blazor: JavaScript mit statischem serverseitigem Rendering (statisches SSR).
Erzeugen eines URI relativ zum Basis-URI-Präfix
Ausgehend vom Basis-URI der App konvertiert ToBaseRelativePath einen absoluten URI in einen URI, der relativ zum Basis-URI-Präfix ist.
Betrachten Sie das folgenden Beispiel:
try
{
baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
...
}
Wenn der Basis-URI der Anwendung https://localhost:8000 lautet, erhalten Sie die folgenden Ergebnisse:
- Die Übergabe von
https://localhost:8000/segmentininputURIliefert alsbaseRelativePathden Wertsegment. - Die Übergabe von
https://localhost:8000/segment1/segment2ininputURIliefert alsbaseRelativePathden Wertsegment1/segment2.
Wenn der Basis-URI der App nicht mit dem Basis-URI von inputURI übereinstimmt, wird eine ArgumentException ausgelöst.
Die Übergabe von https://localhost:8001/segment in inputURI führt zur folgenden Ausnahme:
System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'
Navigationsverlaufsstatus
NavigationManager verwendet die Verlaufs-API des Browsers, um den Navigationsverlaufstatus zu erhalten, der mit jeder von der App vorgenommenen Speicherortänderung verbunden ist. Der Verlaufsstatus ist besonders bei externen Umleitungsszenarien nützlich, z. B. beim Authentifizieren von Benutzern mit externen Identitätsanbietern. Weitere Informationen dazu finden Sie im Abschnitt Navigationsoptionen.
Navigationsoptionen
Übergeben Sie NavigationOptions an NavigateTo, um die folgenden Verhaltensweisen zu steuern:
-
ForceLoad: Umgehen des clientseitigen Routings. Der Browser ist gezwungen, die neue Seite vom Server zu laden, unabhängig davon, ob der URI vom clientseitigen Router verarbeitet wird oder nicht. Der Standardwert ist
false. -
ReplaceHistoryEntry: Ersetzen des aktuellen Eintrags im Verlaufsstapel. Wenn
false, wird der neue Eintrag an den Verlaufsstapel angefügt. Der Standardwert istfalse. - HistoryEntryState: Ruft den Status ab, der an den Verlaufseintrag angefügt werden soll, oder legt ihn fest.
Navigation.NavigateTo("/path", new NavigationOptions
{
HistoryEntryState = "Navigation state"
});
Weitere Informationen zum Abrufen des Status, der dem Zielverlaufseintrag bei der Verarbeitung von Speicherortänderungen zugeordnet ist, finden Sie im Abschnitt Verarbeiten/Verhindern von Speicherortänderungen.
Abfragezeichenfolgen
Verwenden Sie das -[SupplyParameterFromQuery]Attribut, um anzugeben, dass ein Komponentenparameter aus der Abfragezeichenfolge stammt.
Verwenden Sie das -[SupplyParameterFromQuery]Attribut mit dem -[Parameter]Attribut, um anzugeben, dass ein Komponentenparameter einer routingfähigen Komponente aus der Abfragezeichenfolge stammt.
Hinweis
Komponentenparameter können Abfrageparameterwerte nur in routingfähigen Komponenten mit einer @page-Direktive empfangen.
Nur routingfähige Komponenten empfangen Abfrageparameter direkt, um den Top-Down-Informationsfluss nicht zu unterwandern und um die Reihenfolge der Parameterverarbeitung (sowohl durch das Framework als auch durch die App) zu verdeutlichen. Durch diesen Entwurf werden fast unmerkliche Codefehler vermieden, die dadurch entstehen, dass beim Schreiben des App-Codes eine bestimmte Reihenfolge der Parameterverarbeitung vorausgesetzt wird. Es steht Ihnen frei, benutzerdefinierte kaskadierende Parameter zu definieren oder diese direkt regulären Komponentenparametern zuzuweisen, um Abfrageparameterwerte an nicht routingfähige Komponenten zu übergeben.
Komponentenparameter, die aus der Abfragezeichenfolge bereitgestellt werden, unterstützen die folgenden Typen:
-
bool,DateTime,decimal,double,float,Guid,int, ,long.string - Nullable Varianten der vorhergehenden Typen.
- Arrays der genannten Typen, unabhängig davon, ob sie NULL-Werte zulassen oder nicht.
Die richtige kulturinvariante Formatierung wird für den angegebenen Typ angewendet (CultureInfo.InvariantCulture).
Geben Sie die [SupplyParameterFromQuery]-Eigenschaft des Attributs Name an, um einen Abfrageparameternamen zu verwenden, der sich vom Namen des Komponentenparameters unterscheidet. Im folgenden Beispiel lautet der C#-Name des Komponentenparameters {COMPONENT PARAMETER NAME}. Für den Platzhalter {QUERY PARAMETER NAME} wird ein anderer Abfrageparametername angegeben:
Im Gegensatz zu Komponentenparameter-Eigenschaften ([Parameter]) können [SupplyParameterFromQuery]-Eigenschaften zusätzlich zu private mit public gekennzeichnet werden.
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
private string? {COMPONENT PARAMETER NAME} { get; set; }
Genau wie Komponentenparameter-Eigenschaften ([Parameter]) sind [SupplyParameterFromQuery]-Eigenschaften in .NET 6/7 immer public-Eigenschaften. In .NET 8 oder höher können [SupplyParameterFromQuery]-Eigenschaften mit public oder private gekennzeichnet werden.
[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }
Im folgenden Beispiel mit der URL /search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman:
- Die
Filter-Eigenschaft wird inscifi starsaufgelöst. - Die
Page-Eigenschaft wird in3aufgelöst. - Das
Stars-Array wird aus den Abfrageparametern mit den Namenstar(Name = "star") aufgefüllt und inLeVar BurtonundGary Oldmanaufgelöst.
Hinweis
Die Abfragezeichenfolgenparameter in der folgenden Routingseitenkomponente funktionieren auch in einer nicht routingfähigen Komponente ohne Anweisung @page (z. B. Search.razor für eine freigegebene Search-Komponente, die in anderen Komponenten verwendet wird).
Search.razor:
@page "/search"
<h1>Search Example</h1>
<p>Filter: @Filter</p>
<p>Page: @Page</p>
@if (Stars is not null)
{
<p>Stars:</p>
<ul>
@foreach (var name in Stars)
{
<li>@name</li>
}
</ul>
}
@code {
[SupplyParameterFromQuery]
private string? Filter { get; set; }
[SupplyParameterFromQuery]
private int? Page { get; set; }
[SupplyParameterFromQuery(Name = "star")]
private string[]? Stars { get; set; }
}
Search.razor:
@page "/search"
<h1>Search Example</h1>
<p>Filter: @Filter</p>
<p>Page: @Page</p>
@if (Stars is not null)
{
<p>Stars:</p>
<ul>
@foreach (var name in Stars)
{
<li>@name</li>
}
</ul>
}
@code {
[Parameter]
[SupplyParameterFromQuery]
public string? Filter { get; set; }
[Parameter]
[SupplyParameterFromQuery]
public int? Page { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "star")]
public string[]? Stars { get; set; }
}
Verwenden Sie GetUriWithQueryParameter, um einen oder mehrere Abfrageparameter für die aktuelle URL hinzuzufügen, zu ändern oder zu entfernen:
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})
Im vorherigen Beispiel:
- Der
{NAME}-Platzhalter gibt den Namen des Abfrageparameters an. Der{VALUE}-Platzhalter gibt den Wert als unterstützten Typ an. Unterstützte Typen werden weiter unten in diesem Abschnitt aufgeführt. - Eine Zeichenfolge wird mit einem einzelnen Parameter zurückgegeben, der der aktuellen URL entspricht:
- Wird hinzugefügt, wenn der Abfrageparametername in der aktuellen URL nicht vorhanden ist.
- Wird auf den angegebenen Wert aktualisiert, wenn der Abfrageparameter in der aktuellen URL vorhanden ist.
- Wird entfernt, wenn der Typ des angegebenen Werts NULL-Werte zulässt und der Wert
nullist.
- Die richtige kulturinvariante Formatierung wird für den angegebenen Typ angewendet (CultureInfo.InvariantCulture).
- Name und Wert des Abfrageparameters sind URL-codiert.
- Alle Werte mit übereinstimmendem Abfrageparameternamen werden ersetzt, wenn mehrere Instanzen des Typs vorhanden sind.
Rufen Sie GetUriWithQueryParameters auf, um einen aus Uri erstellten URI zu erstellen, wobei mehrere Parameter hinzugefügt, aktualisiert oder entfernt wurden. Für jeden Wert verwendet das Framework value?.GetType(), um den Laufzeittyp für jeden Abfrageparameter zu bestimmen, und wählt die richtige kulturinvariante Formatierung aus. Das Framework löst bei nicht unterstützten Typen einen Fehler aus.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters({PARAMETERS})
Der Platzhalter {PARAMETERS} ist ein IReadOnlyDictionary<string, object>.
Übergeben Sie eine URI-Zeichenfolge an GetUriWithQueryParameters, um einen neuen URI aus einem bereitgestellten URI generieren, wobei mehrere Parameter hinzugefügt, aktualisiert oder entfernt wurden. Für jeden Wert verwendet das Framework value?.GetType(), um den Laufzeittyp für jeden Abfrageparameter zu bestimmen, und wählt die richtige kulturinvariante Formatierung aus. Das Framework löst bei nicht unterstützten Typen einen Fehler aus. Unterstützte Typen werden weiter unten in diesem Abschnitt aufgeführt.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
- Der Platzhalter
{URI}ist der URI mit oder ohne Abfragezeichenfolge. - Der Platzhalter
{PARAMETERS}ist einIReadOnlyDictionary<string, object>.
Unterstützte Typen sind identisch mit unterstützten Typen für Routeneinschränkungen:
boolDateOnlyDateTimedecimaldoublefloatGuidintlongstringTimeOnly
Unter anderem unterstützte Typen:
- Nullable Varianten der vorhergehenden Typen.
- Arrays der genannten Typen, unabhängig davon, ob sie NULL-Werte zulassen oder nicht.
Warnung
Mit standardmäßiger aktivierter Komprimierung vermeiden Sie die Erstellung sicherer (authentifizierter/autorisierter) serverseitiger Komponenten, die Daten aus nicht vertrauenswürdigen Quellen rendern. Nicht vertrauenswürdige Quellen umfassen Routenparameter, Abfragezeichenfolgen, Daten aus JS-Interoperabilität und andere Datenquellen, die ein Drittbenutzer steuern kann (Datenbanken, externe Dienste). Weitere Informationen finden Sie unter ASP.NET Core BlazorSignalR Anleitungen und Anleitung zur Risikominderung für ASP.NET Core Blazor interaktives serverseitiges Rendering.
Abfrageparameterwert ersetzen, wenn der Parameter vorhanden ist
Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
| Aktuelle URL | Generierte URL |
|---|---|
scheme://host/?full%20name=David%20Krumholtz&age=42 |
scheme://host/?full%20name=Morena%20Baccarin&age=42 |
scheme://host/?fUlL%20nAmE=David%20Krumholtz&AgE=42 |
scheme://host/?full%20name=Morena%20Baccarin&AgE=42 |
scheme://host/?full%20name=Jewel%20Staite&age=42&full%20name=Summer%20Glau |
scheme://host/?full%20name=Morena%20Baccarin&age=42&full%20name=Morena%20Baccarin |
scheme://host/?full%20name=&age=42 |
scheme://host/?full%20name=Morena%20Baccarin&age=42 |
scheme://host/?full%20name= |
scheme://host/?full%20name=Morena%20Baccarin |
Abfrageparameter und -wert anfügen, wenn der Parameter nicht vorhanden ist
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
| Aktuelle URL | Generierte URL |
|---|---|
scheme://host/?age=42 |
scheme://host/?age=42&name=Morena%20Baccarin |
scheme://host/ |
scheme://host/?name=Morena%20Baccarin |
scheme://host/? |
scheme://host/?name=Morena%20Baccarin |
Abfrageparameter ersetzen, wenn der Parameterwert null ist
Navigation.GetUriWithQueryParameter("full name", (string)null)
| Aktuelle URL | Generierte URL |
|---|---|
scheme://host/?full%20name=David%20Krumholtz&age=42 |
scheme://host/?age=42 |
scheme://host/?full%20name=Sally%20Smith&age=42&full%20name=Summer%20Glau |
scheme://host/?age=42 |
scheme://host/?full%20name=Sally%20Smith&age=42&FuLl%20NaMe=Summer%20Glau |
scheme://host/?age=42 |
scheme://host/?full%20name=&age=42 |
scheme://host/?age=42 |
scheme://host/?full%20name= |
scheme://host/ |
Abfrageparameter hinzufügen, aktualisieren und entfernen
Im folgenden Beispiel:
-
namewird entfernt, sofern vorhanden. -
agewird mit dem Wert25(int) hinzugefügt, wenn nicht bereits vorhanden. Wenn vorhanden, wirdageauf den Wert25aktualisiert. -
eye colorwird hinzugefügt oder auf den Wertgreenaktualisiert.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["name"] = null,
["age"] = (int?)25,
["eye color"] = "green"
})
| Aktuelle URL | Generierte URL |
|---|---|
scheme://host/?name=David%20Krumholtz&age=42 |
scheme://host/?age=25&eye%20color=green |
scheme://host/?NaMe=David%20Krumholtz&AgE=42 |
scheme://host/?age=25&eye%20color=green |
scheme://host/?name=David%20Krumholtz&age=42&keepme=true |
scheme://host/?age=25&keepme=true&eye%20color=green |
scheme://host/?age=42&eye%20color=87 |
scheme://host/?age=25&eye%20color=green |
scheme://host/? |
scheme://host/?age=25&eye%20color=green |
scheme://host/ |
scheme://host/?age=25&eye%20color=green |
Unterstützung für aufzählbare Werte
Im folgenden Beispiel:
-
full namewird hinzugefügt oder auf den einzelnen WertMorena Baccarinaktualisiert. -
ping-Parameter werden hinzugefügt oder durch35,16,87und240ersetzt.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["full name"] = "Morena Baccarin",
["ping"] = new int?[] { 35, 16, null, 87, 240 }
})
| Aktuelle URL | Generierte URL |
|---|---|
scheme://host/?full%20name=David%20Krumholtz&ping=8&ping=300 |
scheme://host/?full%20name=Morena%20Baccarin&ping=35&ping=16&ping=87&ping=240 |
scheme://host/?ping=8&full%20name=David%20Krumholtz&ping=300 |
scheme://host/?ping=35&full%20name=Morena%20Baccarin&ping=16&ping=87&ping=240 |
scheme://host/?ping=8&ping=300&ping=50&ping=68&ping=42 |
scheme://host/?ping=35&ping=16&ping=87&ping=240&full%20name=Morena%20Baccarin |
Navigieren mit einer hinzugefügten oder geänderten Abfragezeichenfolge
Um mit einer hinzugefügten oder geänderten Abfragezeichenfolge zu navigieren, übergeben Sie eine generierte URL an NavigateTo.
Aufrufe im folgenden Beispiel:
-
GetUriWithQueryParameter, um den Abfrageparameter
namemit dem WertMorena Baccarinhinzuzufügen oder zu ersetzen. - Ruft NavigateTo auf, um die Navigation zur neuen URL auszulösen.
Navigation.NavigateTo(
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));
Die Abfragezeichenfolge einer Anforderung wird von der NavigationManager.Uri-Eigenschaft abgerufen:
@inject NavigationManager Navigation
...
var query = new Uri(Navigation.Uri).Query;
Um die Parameter einer Abfragezeichenfolge zu analysieren, besteht ein Ansatz in der Verwendung von URLSearchParams mit JavaScript (JS) Interop:
export createQueryString = (string queryString) => new URLSearchParams(queryString);
Weitere Informationen zur JavaScript-Isolation mit JavaScript-Modulen finden Sie unter Aufrufen von JavaScript-Funktionen über .NET-Methoden in Blazor in ASP.NET Core.
Navigieren zu benannten Elementen
Navigieren Sie über die folgenden Ansätze mithilfe eines hashbasierten Elementverweises (#) zu einem benannten Element. Für Routen zu Elementen innerhalb einer Komponente und Routen zu Elementen in externen Komponenten werden stammrelative Pfade verwendet. Der führende Schrägstrich (/) ist optional.
Beispiele für jeden der folgenden Ansätze zeigen die Navigation zu einem Element mit einem id-Wert von targetElement in der Counter-Komponente.
Ankerelement (
<a>) mithref:<a href="/counter#targetElement">NavLink-Komponente mit
href:<NavLink href="/counter#targetElement">NavigationManager.NavigateTo übergibt die relative URL:
Navigation.NavigateTo("/counter#targetElement");
Im folgenden Beispiel wird das Navigieren zu benannten H2-Überschriften innerhalb einer Komponente und zu externen Komponenten veranschaulicht.
Platzieren Sie in den Home- (Home.razor) und Counter-Komponenten (Counter.razor) das folgende Markup für die Navigationsziele am unteren Rand des vorhandenen Komponentenmarkups.
<div> erzeugt künstlichen vertikalen Raum, um das Scrollverhalten des Browsers zu veranschaulichen:
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
Fügen Sie der App die folgende FragmentRouting-Komponente hinzu.
FragmentRouting.razor:
@page "/fragment-routing"
@inject NavigationManager Navigation
<PageTitle>Fragment routing</PageTitle>
<h1>Fragment routing to named elements</h1>
<ul>
<li>
<a href="/fragment-routing#targetElement">
Anchor in this component
</a>
</li>
<li>
<a href="/#targetElement">
Anchor to the <code>Home</code> component
</a>
</li>
<li>
<a href="/counter#targetElement">
Anchor to the <code>Counter</code> component
</a>
</li>
<li>
<NavLink href="/fragment-routing#targetElement">
Use a `NavLink` component in this component
</NavLink>
</li>
<li>
<button @onclick="NavigateToElement">
Navigate with <code>NavigationManager</code> to the
<code>Counter</code> component
</button>
</li>
</ul>
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
@code {
private void NavigateToElement()
{
Navigation.NavigateTo("/counter#targetElement");
}
}
Verarbeiten/Verhindern von Standortänderungen
RegisterLocationChangingHandler registriert einen Handler zum Verarbeiten eingehender Navigationsereignisse. Der durch LocationChangingContext bereitgestellte Kontext des Handlers umfasst die folgenden Eigenschaften:
- TargetLocation: Ruft das Ziel ab.
- HistoryEntryState: Ruft den Status ab, der dem Zielverlaufseintrag zugeordnet ist.
- IsNavigationIntercepted: Ruft ab, ob die Navigation von einem Link abgefangen wurde.
- CancellationToken: Ruft CancellationToken ab, um zu ermitteln, ob die Navigation abgebrochen wurde. So kann z. B. festgestellt werden, ob der Benutzer eine andere Navigation ausgelöst hat.
- PreventNavigation: Wird aufgerufen, um zu verhindern, dass die Navigation fortgesetzt wird.
Eine Komponente kann in der OnAfterRender{Async}-Lebenszyklusmethode mehrere Ortswechsel-Handler registrieren. Die Navigation ruft alle registrierten Ortsänderungshandler in der gesamten App (über mehrere Komponenten hinweg) auf, und jede interne Navigation führt sie alle parallel aus. Zusätzlich zu NavigateTo werden Handler aufgerufen.
- Wenn Sie interne Links auswählen, also Links, die auf URLs unter dem Basispfad der App verweisen.
- Beim Navigieren mit den Schaltflächen „Vorwärts“ und „Zurück“ in einem Browser.
Handler werden nur für interne Navigation innerhalb der App ausgeführt. Wenn der Benutzer einen Link auswählt, der zu einer anderen Website führt, oder die Adressleiste manuell auf eine andere Website ändert, werden die Handler für Standortänderungen nicht ausgeführt.
Implementieren Sie IDisposable, und verwerfen Sie registrierte Handler, um ihre Registrierung aufzuheben. Weitere Informationen finden Sie unter ASP.NET Core Razor Komponentenentsorgung.
Von Bedeutung
Versuchen Sie nicht, DOM-Bereinigungsaufgaben per JavaScript-Interoperabilität (JS) auszuführen, wenn Positionsänderungen verarbeitet werden. Verwenden Sie das MutationObserver-Muster in JS auf dem Client. Weitere Informationen finden Sie unter ASP.NET Core Blazor JavaScript-Interoperabilität (JS Interop).
Im folgenden Beispiel wird ein Speicherortänderungshandler für Navigationsereignisse registriert.
NavHandler.razor:
@page "/nav-handler"
@implements IDisposable
@inject NavigationManager Navigation
<p>
<button @onclick="@(() => Navigation.NavigateTo("/"))">
Home (Allowed)
</button>
<button @onclick="@(() => Navigation.NavigateTo("/counter"))">
Counter (Prevented)
</button>
</p>
@code {
private IDisposable? registration;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
registration =
Navigation.RegisterLocationChangingHandler(OnLocationChanging);
}
}
private ValueTask OnLocationChanging(LocationChangingContext context)
{
if (context.TargetLocation == "/counter")
{
context.PreventNavigation();
}
return ValueTask.CompletedTask;
}
public void Dispose() => registration?.Dispose();
}
Da die interne Navigation asynchron abgebrochen werden kann, kann es zu mehreren sich überlappenden Aufrufen registrierter Handler kommen. Beispielsweise können mehrere Handleraufrufe auftreten, wenn der Benutzer die Schaltfläche „Zurück“ auf einer Seite schnell auswählt oder mehrere Links auswählt, bevor eine Navigation ausgeführt wird. Nachfolgend finden Sie eine Zusammenfassung der asynchronen Navigationslogik:
- Wenn ein Speicherortänderungshandler registriert ist, werden wird die gesamte Navigation anfangs rückgängig gemacht und dann erneut wiedergegeben, wenn die Navigation nicht abgebrochen wird.
- Wenn sich überschneidende Navigationsanforderungen vorgenommen werden, wird die neueste Anforderung immer frühere Anforderungen abbrechen, was Folgendes bedeutet:
- Die App kann mehrere Schaltflächenauswahlen von „Zurück“ und „Vorwärts“ als einzelne Auswahl behandeln.
- Wenn der Benutzer mehrere Links auswählt, bevor die Navigation abgeschlossen ist, bestimmt der letzte ausgewählte Link die Navigation.
Weitere Informationen zum Übergeben von NavigationOptions an NavigateTo, um Einträge und den Status des Navigationsverlaufsstapels zu steuern, finden Sie im Abschnitt Navigationsoptionen.
Weiteren Beispielcode finden Sie in der NavigationManagerComponent in BasicTestApp (dotnet/aspnetcore-Referenzquelle).
Hinweis
Dokumentationslinks zur .NET-Referenzquelle laden in der Regel die Standard-Branch des Repositorys, die die aktuelle Entwicklung der nächsten Version von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).
Die NavigationLock-Komponente fängt Navigationsereignisse ab, solange sie gerendert werden, und „sperrt“ damit praktisch jegliche Navigation, bis eine Entscheidung getroffen wurde, fortzufahren oder abzubrechen. Verwenden Sie NavigationLock, wenn das Abfangen der Navigation auf die Lebensdauer einer Komponente begrenzt werden kann.
NavigationLock-Parameter:
-
ConfirmExternalNavigation legt ein Browserdialogfeld fest, um den Benutzer aufzufordern, die externe Navigation zu bestätigen oder abzubrechen. Der Standardwert ist
false. Das Anzeigen des Bestätigungsdialogfelds erfordert anfängliche Benutzerinteraktion mit der Seite, bevor die externe Navigation mit der URL in der Adressleiste des Browsers ausgelöst wird. Weitere Informationen zur Interaktionsanforderung finden Sie unter "Window:beforeunloadevent". - OnBeforeInternalNavigation legt einen Rückruf für interne Navigationsereignisse fest.
In der folgenden NavLock-Komponente:
- Ein Versuch, dem Link zur Website von Microsoft zu folgen, muss vom Benutzer bestätigt werden, bevor die Navigation zu
https://www.microsoft.comerfolgreich ist. -
PreventNavigation wird aufgerufen, um die Navigation zu verhindern, wenn der Benutzer es ablehnt, die Navigation über einen JavaScript (JS) Interop-Aufruf zu bestätigen, der das JS
confirm-Dialogfeld erzeugt.
NavLock.razor:
@page "/nav-lock"
@inject IJSRuntime JSRuntime
@inject NavigationManager Navigation
<NavigationLock ConfirmExternalNavigation="true"
OnBeforeInternalNavigation="OnBeforeInternalNavigation" />
<p>
<button @onclick="Navigate">Navigate</button>
</p>
<p>
<a href="https://www.microsoft.com">Microsoft homepage</a>
</p>
@code {
private void Navigate()
{
Navigation.NavigateTo("/");
}
private async Task OnBeforeInternalNavigation(LocationChangingContext context)
{
var isConfirmed = await JSRuntime.InvokeAsync<bool>("confirm",
"Are you sure you want to navigate to the root page?");
if (!isConfirmed)
{
context.PreventNavigation();
}
}
}
Weiteren Beispielcode finden Sie in der ConfigurableNavigationLock-Komponente in BasicTestApp (dotnet/aspnetcore-Referenzquelle).
Dynamisch generierte NavLink Komponenten über Spiegelung
NavLink Komponenteneinträge können dynamisch über Spiegelung aus den Komponenten der App erstellt werden. Im folgenden Beispiel wird der allgemeine Ansatz für weitere Anpassungen veranschaulicht.
Für die folgende Demonstration wird eine einheitliche Standardbenennungskonvention für die App-Komponenten verwendet:
- Routingfähige Komponentendateinamen verwenden Pascal Case, zum Beispiel
Pages/ProductDetail.razor. - Dateipfade für weiterleitbare Komponenten stimmen mit ihren URLs in Kebab-Schreibweise‡ überein, wobei in der Routenvorlage einer Komponente Bindestriche zwischen Wörtern erscheinen. Beispielsweise wird die Komponente
ProductDetailmit der Routenvorlage/product-detail(@page "/product-detail") in einem Browser an der relativen URL/product-detailangefordert.
Bei der Pascal-Schreibweise (auch Upper-Camel-Case genannt) handelt es sich um eine Namenskonvention ohne Leerzeichen und Interpunktion, wobei der erste Buchstabe jedes Worts, einschließlich des ersten, großgeschrieben wird.
‡Kebab Case ist eine Benennungskonvention ohne Leerzeichen und Interpunktion, die Kleinbuchstaben und Bindestriche zwischen Wörtern verwendet.
Im Razor Markup der NavMenu Komponente (NavMenu.razor) unter der Standardseite Home werden NavLink Komponenten aus einer Auflistung hinzugefügt:
<div class="nav-scrollable"
onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu"
aria-hidden="true"></span> Home
</NavLink>
</div>
+ @foreach (var name in GetRoutableComponents())
+ {
+ <div class="nav-item px-3">
+ <NavLink class="nav-link"
+ href="@Regex.Replace(name, @"(\B[A-Z]|\d+)", "-$1").ToLower()">
+ @Regex.Replace(name, @"(\B[A-Z]|\d+)", " $1")
+ </NavLink>
+ </div>
+ }
</nav>
</div>
Die GetRoutableComponents Methode im @code Block:
public IEnumerable<string> GetRoutableComponents() =>
Assembly.GetExecutingAssembly()
.ExportedTypes
.Where(t => t.IsSubclassOf(typeof(ComponentBase)))
.Where(c => c.GetCustomAttributes(inherit: true)
.OfType<RouteAttribute>()
.Any())
.Where(c => c.Name != "Home" && c.Name != "Error")
.OrderBy(o => o.Name)
.Select(c => c.Name);
Im vorherigen Beispiel werden die folgenden Seiten nicht in die gerenderte Liste der Komponenten eingeschlossen:
-
HomeSeite: Die Seite wird separat von den automatisch generierten Links aufgelistet, da sie oben in der Liste angezeigt wird und denMatchParameter festlegen soll. -
ErrorSeite: Diese Fehlerseite wird nur vom Framework aufgerufen und sollte nicht angezeigt werden.
Rufen Sie zur Demonstration des vorherigen Codes in einer Beispiel-App die