Routing und Navigation in ASP.NET Core Blazor

In diesem Artikel wird erläutert, wie Sie das Anforderungsrouting verwalten und wie Sie die NavLink-Komponente verwenden, um Navigationslinks in Blazor-Apps zu erstellen.

Wichtig

Die Codebeispiele in diesem Artikel zeigen Methoden, die für Navigation aufgerufen werden, einen in Klassen und Komponenten injizierten NavigationManager.

Routenvorlagen

Die Router-Komponente ermöglicht das Routing an Razor-Komponenten in einer Blazor-App. Die Router-Komponente wird in der App-Komponente von Blazor-Apps verwendet.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

Wenn eine Razor-Komponente (.razor) mit einer @page-Anweisung kompiliert wird, wird für die generierte Komponentenklasse ein RouteAttribute-Objekt bereitgestellt, das die Routenvorlage der Komponente angibt.

Wenn die App gestartet wird, wird die Assembly gescannt, die als AppAssembly-Objekt des Routers angegeben wurde, um Routeninformationen für die Komponenten der App zu erfassen, die über ein RouteAttribute-Objekt verfügen.

Zur Laufzeit führt die RouteView-Komponente Folgendes aus:

  • Sie empfängt das RouteData-Objekt vom Router-Objekt zusammen mit den Routenparametern.
  • Sie rendert die angegebene Komponente mit deren Layout, einschließlich aller weiteren geschachtelten Layouts.

Optional können Sie einen DefaultLayout-Parameter mit einer Layoutklasse für Komponenten angeben, die kein Layout mit der @layout-Anweisung festlegen. Die Blazor-Projektvorlagen des Frameworks geben die MainLayout-Komponente (Shared/MainLayout.razor) als Standardlayout der App an. Weitere Informationen zu Layouts finden Sie unter Blazor-Layouts in ASP.NET Core.

Komponenten unterstützen mehrere Routenvorlagen mithilfe mehrerer @page-Anweisungen. Die folgende Beispielkomponente lädt Anforderungen für /blazor-route und /different-blazor-route.

Pages/BlazorRoute.razor:

@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

Wichtig

Damit URLs ordnungsgemäß aufgelöst werden können, muss die App das Tag <base> (Speicherort des <head>-Inhalts) mit dem im Attribut href angegebenen App-Basispfad enthalten. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor in ASP.NET Core.

Alternativ zur Angabe der Routenvorlage als Zeichenfolgenliteral mit der Anweisung @page können konstantenbasierte Routenvorlagen mit der @attribute-Anweisung angegeben werden.

Im folgenden Beispiel wird die Anweisung @page in einer Komponente durch die Anweisung @attribute und die konstantenbasierte Routenvorlage in Constants.CounterRoute ersetzt, die an anderer Stelle in der App auf /counter festgelegt wird:

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

Fokussieren eines Elements bei der Navigation

Verwenden Sie die FocusOnNavigate-Komponente, um den UI-Fokus auf Grundlage eines CSS-Selektors auf ein Element zu setzen, nachdem Sie von einer Seite zu einer anderen navigiert sind. Ein Beispiel für die Verwendung der FocusOnNavigate-Komponente ist die App-Komponente einer mit der Blazor-Projektvorlage erstellten App.

In App.razor:

<FocusOnNavigate RouteData="@routeData" Selector="h1" />

Wenn die Router-Komponente zu einer neuen Seite navigiert, legt die FocusOnNavigate-Komponente den Fokus auf den Header der obersten Ebene (<h1>) der Seite fest. Dies ist eine gängige Strategie, um sicherzustellen, dass eine Seitennavigation bei Verwendung der Sprachausgabe angekündigt wird.

Bereitstellen von benutzerdefiniertem Inhalt, wenn kein Inhalt gefunden wurde

Die Router-Komponente ermöglicht es der App, benutzerdefinierte Inhalte anzugeben, wenn für die angeforderte Route keine Inhalte gefunden werden.

In der App-Komponente können Sie benutzerdefinierten Inhalt in der Router-Vorlage der NotFound-Komponente festlegen.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <h1>Sorry</h1>
        <p>Sorry, there's nothing at this address.</p> b
    </NotFound>
</Router>

Beliebige Elemente werden als Inhalt der <NotFound>-Tags unterstützt, z. B. andere interaktive Komponenten. Informationen zum Anwenden eines Standardlayouts auf NotFound-Inhalte finden Sie unter Blazor-Layouts in ASP.NET Core.

Weiterleiten an Komponenten aus mehreren Assemblys

Verwenden Sie den AdditionalAssemblies-Parameter, um zusätzliche Assemblys anzugeben, die die Router-Komponente bei der Suche nach für das Routing geeigneten Komponenten beachten soll. Zusätzliche Assemblys werden neben der für AppAssembly angegebenen Assembly gescannt. Im folgenden Beispiel ist Component1 eine für das Routing geeignete Komponente, die in einer Komponentenklassenbibliothek definiert ist, auf die verwiesen wird. Im folgenden AdditionalAssemblies-Beispiel wird Routing für Component1 unterstützt.

App.razor:

<Router
    AppAssembly="@typeof(App).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

Routenparameter

Der Router verwendet Routenparameter, um die entsprechenden Komponentenparameter mit demselben Namen aufzufüllen. Bei den Routenparameternamen muss die Groß- und Kleinschreibung nicht berücksichtigt werden. Im folgenden Beispiel weist der Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn eine Anforderung für /route-parameter-1/amazing erfolgt, wird der Inhalt der <h1>-Tags als Blazor is amazing! gerendert.

Pages/RouteParameter1.razor:

@page "/route-parameter-1/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string? Text { get; set; }
}

Optionale Parameter werden unterstützt. Im folgenden Beispiel weist der optionale Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn das Segment nicht vorhanden ist, wird der Wert von Text auf fantastic festgelegt.

Pages/RouteParameter2.razor:

@page "/route-parameter-2/{text?}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string? Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

Verwenden Sie OnParametersSet anstelle von OnInitialized{Async}, um die App-Navigation zur gleichen Komponente mit einem anderen optionalen Parameterwert zuzulassen. Verwenden Sie auf der Grundlage des vorangehenden Beispiels OnParametersSet, wenn der Benutzer in der Lage sein soll, von /route-parameter-2 zu /route-parameter-2/amazing oder von /route-parameter-2/amazing zu /route-parameter-2 zu navigieren:

protected override void OnParametersSet()
{
    Text = Text ?? "fantastic";
}

Routeneinschränkungen

Eine Routeneinschränkung erzwingt die Typübereinstimmung in einem Routensegment zu einer Komponente.

Im folgenden Beispiel stimmt die Route zur User-Komponente nur überein, wenn:

  • ein Id-Routensegment in der Anforderungs-URL vorhanden ist.
  • das Id-Segment ein Integer (int) ist.

Pages/User.razor:

@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Die in der folgenden Tabelle aufgeführten Routeneinschränkungen sind verfügbar. Informationen zu den Routeneinschränkungen der invarianten Kultur finden Sie in der Warnung unter der Tabelle.

Constraint Beispiel Beispiele für Übereinstimmungen Invariante
Kultur
Übereinstimmend
bool {active:bool} true, FALSE Nein
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Ja
decimal {price:decimal} 49.99, -1,000.01 Ja
double {weight:double} 1.234, -1,001.01e8 Ja
float {weight:float} 1.234, -1,001.01e8 Ja
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Nein
int {id:int} 123456789, -123456789 Ja
long {ticks:long} 123456789, -123456789 Ja

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.

Routeneinschränkungen funktionieren auch mit optionalen Parametern. Im folgenden Beispiel ist Id erforderlich, während Option ein optionaler boolescher Routenparameter ist.

Pages/User.razor:

@page "/user/{Id:int}/{Option:bool?}"

<p>
    Id: @Id
</p>

<p>
    Option: @Option
</p>

@code {
    [Parameter]
    public int Id { get; set; }

    [Parameter]
    public bool Option { get; set; }
}

Routing mit URLs, die Punkte enthalten

Wenn das letzte Segment einer Anforderungs-URL einen Punkt (.) enthält, wird bei gehosteten Blazor WebAssembly- und Blazor Server-Apps von der serverseitigen Standardvorlage für Routen davon ausgegangen, dass eine Datei angefordert wird. Beispielsweise wird die URL /example/some.thing vom Router als Anforderung für eine Datei mit dem Namen some.thing interpretiert. Ohne zusätzliche Konfiguration gibt eine App die Antwort 404 – Nicht gefunden zurück, wenn some.thing an eine Komponente mit einer @page-Anweisung weiterleiten sollte und some.thing ein Routenparameterwert ist. Wenn eine Route mit mindestens einem Parameter verwendet werden soll, der einen Punkt enthält, muss die Route von der App mit einer benutzerdefinierten Vorlage konfiguriert werden.

Sehen Sie sich z. B. die folgende Example-Komponente an, die einen Routenparameter aus dem letzten Segment der URL empfangen kann.

Pages/Example.razor:

@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}

Wenn Sie der Server-App einer gehosteten Blazor WebAssembly-Lösung erlauben möchten, dass sie die Anforderung mit einem Punkt im param-Routenparameter weiterleitet, fügen Sie eine Ausweichdatei-Routenvorlage mit dem optionale Parameter in Program.cs hinzu:

app.MapFallbackToFile("/example/{param?}", "index.html");

Fügen Sie eine Ausweichdateiroutenvorlage hinzu, wobei sich der optionale Parameter in Program.cs befindet, um eine Blazor Server-App so zu konfigurieren, dass die Anforderung mit einem Punkt im param-Routenparameter weiterleitet wird:

app.MapFallbackToPage("/example/{param?}", "/_Host");

Weitere Informationen finden Sie unter Routing in ASP.NET Core.

Catch-All-Routenparameter

Catch-All-Routenparameter, die Pfade über mehrere Ordnergrenzen hinweg erfassen, werden in Komponenten unterstützt.

Für Catch-All-Routenparameter gilt:

  • Sie müssen so benannt werden, dass sie dem Routensegmentnamen entsprechen. Die Groß-/Kleinschreibung muss bei der Benennung nicht beachtet werden.
  • Ein string-Typ. Im Framework steht keine automatische Übertragung zur Verfügung.
  • Am Ende der URL.

Pages/CatchAll.razor:

@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}

Bei der URL /catch-all/this/is/a/test mit der Routenvorlage /catch-all/{*pageRoute} wird der Wert für PageRoute auf this/is/a/test festgelegt.

Schrägstriche und Segmente des erfassten Pfads werden decodiert. Bei der Routenvorlage /catch-all/{*pageRoute} hält die URL /catch-all/this/is/a%2Ftest%2Athis/is/a/test* an.

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.

Member Beschreibung
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:
  • Clientseitiges Routing wird umgangen.
  • Der Browser ist gezwungen, die neue Seite vom Server zu laden, unabhängig davon, ob der URI normalerweise vom clientseitigen Router verarbeitet wird oder nicht.
Wenn 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 Wenn ein Basis-URI (z. B. ein URI, der zuvor von BaseUri zurückgegeben wurde) vorhanden ist, wird ein absoluter URI in einen URI relativ zum Basis-URI-Präfix konvertiert.
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.

Andere Speicherorte

Für das LocationChanged-Ereignis bietet LocationChangedEventArgs die folgenden Informationen zu Navigationsereignissen:

Die folgende Komponente führt folgende Aktionen aus:

  • Sie navigiert zur Counter-Komponente der App (Pages/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, wenn Dispose vom 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

Pages/Navigate.razor:

@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code 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 Beseitigung von Komponenten finden Sie unter Lebenszyklus von Razor-Komponenten in ASP.NET Core.

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.

Ü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 ist false.
  • 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 mit dem [Parameter]-Attribut, um anzugeben, dass ein Komponentenparameter einer routingfähigen Komponente aus der Abfragezeichenfolge stammen kann.

Hinweis

Komponentenparameter können Abfrageparameterwerte nur in routingfähigen Komponenten mit einer @page-Direktive empfangen.

Komponentenparameter, die aus der Abfragezeichenfolge bereitgestellt werden, unterstützen die folgenden Typen:

  • bool, DateTime, decimal, double, float, Guid, int, long, string.
  • Nullwerte zulassende Varianten des vorhergehenden Typs.
  • 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 Name-Eigenschaft des Attributs [SupplyParameterFromQuery] 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:

[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 in scifi stars aufgelöst.
  • Die Page-Eigenschaft wird in 3 aufgelöst.
  • Das Stars-Array wird aus den Abfrageparametern mit den Namen star (Name = "star") aufgefüllt und in LeVar Burton und Gary Oldman aufgelöst.

Pages/Search.razor:

@page "/search"

<h1>Search Example</h1>

<p>Filter: @Filter</p>

<p>Page: @Page</p>

@if (Stars is not null)
{
    <p>Assignees:</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 NavigationManager.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 null ist.
  • 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 NavigationManager.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 ein IReadOnlyDictionary<string, object>.

Unterstützte Typen sind identisch mit unterstützten Typen für Routeneinschränkungen:

  • bool
  • DateTime
  • decimal
  • double
  • float
  • Guid
  • int
  • long
  • string

Unter anderem unterstützte Typen:

  • Nullwerte zulassende Varianten des vorhergehenden Typs.
  • Arrays der genannten Typen, unabhängig davon, ob sie NULL-Werte zulassen oder nicht.

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

Siehe folgendes Beispiel:

  • name wird entfernt, sofern vorhanden.
  • age wird mit dem Wert 25 (int) hinzugefügt, falls nicht vorhanden. Wenn vorhanden, wird age auf den Wert 25 aktualisiert.
  • eye color wird hinzugefügt oder auf den Wert green aktualisiert.
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

Siehe folgendes Beispiel:

  • full name wird hinzugefügt oder auf den einzelnen Wert Morena Baccarin aktualisiert.
  • ping-Parameter werden hinzugefügt oder durch 35, 16, 87 und 240 ersetzt.
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

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 name mit dem Wert Morena Baccarin hinzuzufügen oder zu ersetzen.
  • Ruft NavigateTo auf, um die Navigation zur neuen URL auszulösen.
Navigation.NavigateTo(
    Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));

Benutzerinteraktion mit <Navigating>-Inhalt

Die Router-Komponente zeigt dem Benutzer, dass ein Seitenübergang erfolgt.

Fügen Sie oben in der App-Komponente (App.razor) eine @using-Anweisung für den Microsoft.AspNetCore.Components.Routing-Namespace hinzu:

@using Microsoft.AspNetCore.Components.Routing

Fügen Sie der Komponente ein <Navigating>-Tag mit Markup für die Anzeige während Seitenübergangsereignissen hinzu. Weitere Informationen finden Sie unter Navigating (in der API-Dokumentation).

Im Routerelementinhalt (<Router>...</Router>) der App-Komponente (App.razor):

<Navigating>
    <p>Loading the requested page&hellip;</p>
</Navigating>

Ein Beispiel, in dem die Navigating-Eigenschaft verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Behandeln von asynchronen Navigationsereignissen mit OnNavigateAsync

Die Router-Komponente unterstützt ein OnNavigateAsync-Feature. Der OnNavigateAsync-Handler wird aufgerufen, wenn der Benutzer:

  • zum ersten Mal eine Route benutzt, indem er direkt über den Browser dorthin navigiert.
  • Zu einer neuen Route mithilfe eines Links oder eines NavigationManager.NavigateTo-Aufrufs navigiert.

In der App-Komponente (App.razor):

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}

Ein Beispiel, in dem OnNavigateAsync verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Beim Prerendering auf dem Server in einer Blazor Server-App oder gehosteten Blazor WebAssembly-App wird OnNavigateAsynczweimal ausgeführt:

  • Einmal, wenn die angeforderte Endpunktkomponente zuerst statisch als Teil der Seite gerendert wird.
  • Ein zweites Mal, wenn der Browser die Endpunktkomponente rendert.

Die App-Komponente kann das NavigationContext-Objekt zur Verwendung in OnAfterRender{Async} speichern, um zu verhindern, dass Entwicklercode in OnNavigateAsync zweimal ausgeführt wird. Dort kann das firstRender-Objekt auch überprüft werden. Weitere Informationen finden Sie unter Voarabrendering mit JavaScript-Interop im Artikel Blazor-Lebenszyklus.

Verarbeiten von Abbrüchen in OnNavigateAsync

Das NavigationContext-Objekt, das an den OnNavigateAsync-Rückruf übergeben wird, enthält ein CancellationToken, das beim Auftreten eines neuen Navigationsereignisses festgelegt wird. Der OnNavigateAsync-Rückruf muss ausgelöst werden, wenn dieses Abbruchtoken festgelegt wird, um zu vermeiden, dass der OnNavigateAsync-Rückruf für eine veraltete Navigation weiterhin ausgeführt wird.

Wenn ein Benutzer zu einem Endpunkt navigiert, aber dann sofort zu einem neuen Endpunkt wechselt, sollte die App den OnNavigateAsync-Rückruf für den ersten Endpunkt nicht weiter ausführen.

Für das folgende App-Komponentenbeispiel gilt Folgendes:

  • Das Abbruchtoken wird im Aufruf von PostAsJsonAsync übergeben, der den POST-Vorgang abbrechen kann, wenn der Benutzer vom /about-Endpunkt weg navigiert.
  • Das Abbruchtoken wird während eines Produktvorabrufs festgelegt, wenn der Benutzer vom /store-Endpunkt weg navigiert.

App.razor:

@inject HttpClient Http
@inject ProductCatalog Products

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext context)
    {
        if (context.Path == "/about") 
        {
            var stats = new Stats { Page = "/about" };
            await Http.PostAsJsonAsync("api/visited", stats, 
                context.CancellationToken);
        }
        else if (context.Path == "/store")
        {
            var productIds = [345, 789, 135, 689];

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}

Hinweis

Wenn der Rückruf nicht ausgelöst wird, wenn das Abbruchtoken in NavigationContext abgebrochen wird, kann dies zu unbeabsichtigtem Verhalten führen, z. B. zum Rendern einer Komponente aus einer vorherigen Navigation.

Verarbeiten/Verhindern von Speicherortänderungen

RegisterLocationChangingHandler registriert einen Handler zum Verarbeiten eingehender Navigationsereignisse. Der durch LocationChangingContext bereitgestellte Kontext des Handlers umfasst die folgenden Eigenschaften:

Eine Komponente kann mehrere Speicherortänderungshandler in ihren OnAfterRender- oder OnAfterRenderAsync-Methoden registrieren. Die Navigation ruft alle Speicherortänderungshandler auf, die für die gesamte App (über mehrere Komponenten hinweg) registriert sind, und eine beliebige interne Navigation führt sie alle parallel aus. Zusätzlich zu NavigateTo werden Handler unter den folgenden Umständen aufgerufen:

  • Wenn interne Links ausgewählt werden, die Links sind, 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 navigiert oder die Adressleiste manuell in eine andere Website ändert, werden die Speicherortänderungshandler nicht ausgeführt.

Implementieren Sie IDisposable, und verwerfen Sie registrierte Handler, um ihre Registrierung aufzuheben. Weitere Informationen finden Sie unter Rendering von Razor-Komponenten in ASP.NET Core.

Im folgenden Beispiel wird ein Speicherortänderungshandler für Navigationsereignisse registriert.

Pages/NavHandler.razor:

@page "/nav-handler"
@inject NavigationManager Navigation
@implements IDisposable

<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, können mehrere sich überschneidende Aufrufe registrierter Handler auftreten. 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 den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release 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 Fenster: beforeunload-Ereignis (MDN-Dokumentation).
  • 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.com erfolgreich 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 JSconfirm-Dialogfeld erzeugt.

Pages/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 Index page?");

        if (!isConfirmed)
        {
            context.PreventNavigation();
        }
    }
}

Weiteren Beispielcode finden Sie in der ConfigurableNavigationLock-Komponente in BasicTestApp (dotnet/aspnetcore-Referenzquelle).

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.

Hinweis

Die NavMenu-Komponente (NavMenu.razor) wird im Ordner Shared einer App bereitgestellt, die aus den Blazor-Projektvorlagen generiert wurde.

Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:

Im vorherigen Beispiel entspricht HomeNavLinkhref="" der Home-URL und empfängt nur die CSS-Klasse active im Standardbasispfad der App (/). Die zweite NavLink-Komponente empfängt die active-Klasse, wenn der Benutzer eine beliebige URL mit einem component-Präfix aufruft (z. B. /component und /component/another-segment).

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 = 0; c < 10; c++)
{
    var current = c;
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @current
        </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(0,10))
{
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @c
        </NavLink>
    </li>
}

Integration von ASP.NET Core-Endpunktrouting

Dieser Abschnitt gilt nur für Blazor Server-Apps.

Blazor Server ist in das ASP.NET Core-Endpunktrouting integriert. Eine ASP.NET Core-App ist so konfiguriert, dass sie eingehende Verbindungen für interaktive Komponenten mit MapBlazorHub in Program.cs akzeptiert:

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

Die typische Konfiguration ist die Weiterleitung aller Anforderungen an eine Razor-Seite, die als Host für den serverseitigen Teil der Blazor Server-App fungiert. Gemäß der Konvention wird die Hostseite in der Regel im Ordner Pages der App mit _Host.cshtml benannt.

Die in der Hostdatei angegebene Route wird als Fallbackroute bezeichnet, da sie mit einer niedrigen Priorität bei der Routenanpassung arbeitet. Die Ausweichroute wird verwendet, wenn andere Routen nicht passen. Dadurch kann die App andere Controller und Seiten verwenden, ohne das Komponentenrouting in der Blazor Server-App zu beeinträchtigen.

Routenvorlagen

Die Router-Komponente ermöglicht das Routing an Razor-Komponenten in einer Blazor-App. Die Router-Komponente wird in der App-Komponente von Blazor-Apps verwendet.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

Wenn eine Razor-Komponente (.razor) mit einer @page-Anweisung kompiliert wird, wird für die generierte Komponentenklasse ein RouteAttribute-Objekt bereitgestellt, das die Routenvorlage der Komponente angibt.

Wenn die App gestartet wird, wird die Assembly gescannt, die als AppAssembly-Objekt des Routers angegeben wurde, um Routeninformationen für die Komponenten der App zu erfassen, die über ein RouteAttribute-Objekt verfügen.

Zur Laufzeit führt die RouteView-Komponente Folgendes aus:

  • Sie empfängt das RouteData-Objekt vom Router-Objekt zusammen mit den Routenparametern.
  • Sie rendert die angegebene Komponente mit deren Layout, einschließlich aller weiteren geschachtelten Layouts.

Optional können Sie einen DefaultLayout-Parameter mit einer Layoutklasse für Komponenten angeben, die kein Layout mit der @layout-Anweisung festlegen. Die Blazor-Projektvorlagen des Frameworks geben die MainLayout-Komponente (Shared/MainLayout.razor) als Standardlayout der App an. Weitere Informationen zu Layouts finden Sie unter Blazor-Layouts in ASP.NET Core.

Komponenten unterstützen mehrere Routenvorlagen mithilfe mehrerer @page-Anweisungen. Die folgende Beispielkomponente lädt Anforderungen für /blazor-route und /different-blazor-route.

Pages/BlazorRoute.razor:

@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

Wichtig

Damit URLs ordnungsgemäß aufgelöst werden können, muss die App das Tag <base> (Speicherort des <head>-Inhalts) mit dem im Attribut href angegebenen App-Basispfad enthalten. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor in ASP.NET Core.

Alternativ zur Angabe der Routenvorlage als Zeichenfolgenliteral mit der Anweisung @page können konstantenbasierte Routenvorlagen mit der @attribute-Anweisung angegeben werden.

Im folgenden Beispiel wird die Anweisung @page in einer Komponente durch die Anweisung @attribute und die konstantenbasierte Routenvorlage in Constants.CounterRoute ersetzt, die an anderer Stelle in der App auf /counter festgelegt wird:

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

Fokussieren eines Elements bei der Navigation

Verwenden Sie die FocusOnNavigate-Komponente, um den UI-Fokus auf Grundlage eines CSS-Selektors auf ein Element zu setzen, nachdem Sie von einer Seite zu einer anderen navigiert sind. Ein Beispiel für die Verwendung der FocusOnNavigate-Komponente ist die App-Komponente einer mit der Blazor-Projektvorlage erstellten App.

In App.razor:

<FocusOnNavigate RouteData="@routeData" Selector="h1" />

Wenn die Router-Komponente zu einer neuen Seite navigiert, legt die FocusOnNavigate-Komponente den Fokus auf den Header der obersten Ebene (<h1>) der Seite fest. Dies ist eine gängige Strategie, um sicherzustellen, dass eine Seitennavigation bei Verwendung der Sprachausgabe angekündigt wird.

Bereitstellen von benutzerdefiniertem Inhalt, wenn kein Inhalt gefunden wurde

Die Router-Komponente ermöglicht es der App, benutzerdefinierte Inhalte anzugeben, wenn für die angeforderte Route keine Inhalte gefunden werden.

In der App-Komponente können Sie benutzerdefinierten Inhalt in der Router-Vorlage der NotFound-Komponente festlegen.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <h1>Sorry</h1>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

Beliebige Elemente werden als Inhalt der <NotFound>-Tags unterstützt, z. B. andere interaktive Komponenten. Informationen zum Anwenden eines Standardlayouts auf NotFound-Inhalte finden Sie unter Blazor-Layouts in ASP.NET Core.

Weiterleiten an Komponenten aus mehreren Assemblys

Verwenden Sie den AdditionalAssemblies-Parameter, um zusätzliche Assemblys anzugeben, die die Router-Komponente bei der Suche nach für das Routing geeigneten Komponenten beachten soll. Zusätzliche Assemblys werden neben der für AppAssembly angegebenen Assembly gescannt. Im folgenden Beispiel ist Component1 eine für das Routing geeignete Komponente, die in einer Komponentenklassenbibliothek definiert ist, auf die verwiesen wird. Im folgenden AdditionalAssemblies-Beispiel wird Routing für Component1 unterstützt.

App.razor:

<Router
    AppAssembly="@typeof(App).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

Routenparameter

Der Router verwendet Routenparameter, um die entsprechenden Komponentenparameter mit demselben Namen aufzufüllen. Bei den Routenparameternamen muss die Groß- und Kleinschreibung nicht berücksichtigt werden. Im folgenden Beispiel weist der Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn eine Anforderung für /route-parameter-1/amazing erfolgt, wird der Inhalt der <h1>-Tags als Blazor is amazing! gerendert.

Pages/RouteParameter1.razor:

@page "/route-parameter-1/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string? Text { get; set; }
}

Optionale Parameter werden unterstützt. Im folgenden Beispiel weist der optionale Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn das Segment nicht vorhanden ist, wird der Wert von Text auf fantastic festgelegt.

Pages/RouteParameter2.razor:

@page "/route-parameter-2/{text?}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string? Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

Verwenden Sie OnParametersSet anstelle von OnInitialized{Async}, um die App-Navigation zur gleichen Komponente mit einem anderen optionalen Parameterwert zuzulassen. Verwenden Sie auf der Grundlage des vorangehenden Beispiels OnParametersSet, wenn der Benutzer in der Lage sein soll, von /route-parameter-2 zu /route-parameter-2/amazing oder von /route-parameter-2/amazing zu /route-parameter-2 zu navigieren:

protected override void OnParametersSet()
{
    Text = Text ?? "fantastic";
}

Routeneinschränkungen

Eine Routeneinschränkung erzwingt die Typübereinstimmung in einem Routensegment zu einer Komponente.

Im folgenden Beispiel stimmt die Route zur User-Komponente nur überein, wenn:

  • ein Id-Routensegment in der Anforderungs-URL vorhanden ist.
  • das Id-Segment ein Integer (int) ist.

Pages/User.razor:

@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Die in der folgenden Tabelle aufgeführten Routeneinschränkungen sind verfügbar. Informationen zu den Routeneinschränkungen der invarianten Kultur finden Sie in der Warnung unter der Tabelle.

Constraint Beispiel Beispiele für Übereinstimmungen Invariante
Kultur
Übereinstimmend
bool {active:bool} true, FALSE Nein
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Ja
decimal {price:decimal} 49.99, -1,000.01 Ja
double {weight:double} 1.234, -1,001.01e8 Ja
float {weight:float} 1.234, -1,001.01e8 Ja
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Nein
int {id:int} 123456789, -123456789 Ja
long {ticks:long} 123456789, -123456789 Ja

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.

Routeneinschränkungen funktionieren auch mit optionalen Parametern. Im folgenden Beispiel ist Id erforderlich, während Option ein optionaler boolescher Routenparameter ist.

Pages/User.razor:

@page "/user/{Id:int}/{Option:bool?}"

<p>
    Id: @Id
</p>

<p>
    Option: @Option
</p>

@code {
    [Parameter]
    public int Id { get; set; }

    [Parameter]
    public bool Option { get; set; }
}

Routing mit URLs, die Punkte enthalten

Wenn das letzte Segment einer Anforderungs-URL einen Punkt (.) enthält, wird bei gehosteten Blazor WebAssembly- und Blazor Server-Apps von der serverseitigen Standardvorlage für Routen davon ausgegangen, dass eine Datei angefordert wird. Beispielsweise wird die URL https://localhost.com:5001/example/some.thing vom Router als Anforderung für eine Datei mit dem Namen some.thing interpretiert. Ohne zusätzliche Konfiguration gibt eine App die Antwort 404 – Nicht gefunden zurück, wenn some.thing an eine Komponente mit einer @page-Anweisung weiterleiten sollte und some.thing ein Routenparameterwert ist. Wenn eine Route mit mindestens einem Parameter verwendet werden soll, der einen Punkt enthält, muss die Route von der App mit einer benutzerdefinierten Vorlage konfiguriert werden.

Sehen Sie sich z. B. die folgende Example-Komponente an, die einen Routenparameter aus dem letzten Segment der URL empfangen kann.

Pages/Example.razor:

@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}

Wenn Sie der Server-App einer gehosteten Blazor WebAssembly-Lösung erlauben möchten, dass sie die Anforderung mit einem Punkt im param-Routenparameter weiterleitet, fügen Sie eine Ausweichdatei-Routenvorlage mit dem optionale Parameter in Program.cs hinzu:

app.MapFallbackToFile("/example/{param?}", "index.html");

Fügen Sie eine Ausweichdateiroutenvorlage hinzu, wobei sich der optionale Parameter in Program.cs befindet, um eine Blazor Server-App so zu konfigurieren, dass die Anforderung mit einem Punkt im param-Routenparameter weiterleitet wird:

app.MapFallbackToPage("/example/{param?}", "/_Host");

Weitere Informationen finden Sie unter Routing in ASP.NET Core.

Catch-All-Routenparameter

Catch-All-Routenparameter, die Pfade über mehrere Ordnergrenzen hinweg erfassen, werden in Komponenten unterstützt.

Für Catch-All-Routenparameter gilt:

  • Sie müssen so benannt werden, dass sie dem Routensegmentnamen entsprechen. Die Groß-/Kleinschreibung muss bei der Benennung nicht beachtet werden.
  • Ein string-Typ. Im Framework steht keine automatische Übertragung zur Verfügung.
  • Am Ende der URL.

Pages/CatchAll.razor:

@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}

Bei der URL /catch-all/this/is/a/test mit der Routenvorlage /catch-all/{*pageRoute} wird der Wert für PageRoute auf this/is/a/test festgelegt.

Schrägstriche und Segmente des erfassten Pfads werden decodiert. Bei der Routenvorlage /catch-all/{*pageRoute} hält die URL /catch-all/this/is/a%2Ftest%2Athis/is/a/test* an.

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.

Member Beschreibung
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:
  • Clientseitiges Routing wird umgangen.
  • Der Browser ist gezwungen, die neue Seite vom Server zu laden, unabhängig davon, ob der URI normalerweise vom clientseitigen Router verarbeitet wird oder nicht.
Wenn 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 Wenn ein Basis-URI (z. B. ein URI, der zuvor von BaseUri zurückgegeben wurde) vorhanden ist, wird ein absoluter URI in einen URI relativ zum Basis-URI-Präfix konvertiert.
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.

Andere Speicherorte

Für das LocationChanged-Ereignis bietet LocationChangedEventArgs die folgenden Informationen zu Navigationsereignissen:

Die folgende Komponente führt folgende Aktionen aus:

  • Sie navigiert zur Counter-Komponente der App (Pages/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, wenn Dispose vom 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

Pages/Navigate.razor:

@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code 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 Beseitigung von Komponenten finden Sie unter Lebenszyklus von Razor-Komponenten in ASP.NET Core.

Abfragezeichenfolgen

Verwenden Sie das [SupplyParameterFromQuery]-Attribut mit dem [Parameter]-Attribut, um anzugeben, dass ein Komponentenparameter einer routingfähigen Komponente aus der Abfragezeichenfolge stammen kann.

Hinweis

Komponentenparameter können Abfrageparameterwerte nur in routingfähigen Komponenten mit einer @page-Direktive empfangen.

Komponentenparameter, die aus der Abfragezeichenfolge bereitgestellt werden, unterstützen die folgenden Typen:

  • bool, DateTime, decimal, double, float, Guid, int, long, string.
  • Nullwerte zulassende Varianten des vorhergehenden Typs.
  • 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 Name-Eigenschaft des Attributs [SupplyParameterFromQuery] 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:

[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 in scifi stars aufgelöst.
  • Die Page-Eigenschaft wird in 3 aufgelöst.
  • Das Stars-Array wird aus den Abfrageparametern mit den Namen star (Name = "star") aufgefüllt und in LeVar Burton und Gary Oldman aufgelöst.

Pages/Search.razor:

@page "/search"

<h1>Search Example</h1>

<p>Filter: @Filter</p>

<p>Page: @Page</p>

@if (Stars is not null)
{
    <p>Assignees:</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 NavigationManager.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 null ist.
  • 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 NavigationManager.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 ein IReadOnlyDictionary<string, object>.

Unterstützte Typen sind identisch mit unterstützten Typen für Routeneinschränkungen:

  • bool
  • DateTime
  • decimal
  • double
  • float
  • Guid
  • int
  • long
  • string

Unter anderem unterstützte Typen:

  • Nullwerte zulassende Varianten des vorhergehenden Typs.
  • Arrays der genannten Typen, unabhängig davon, ob sie NULL-Werte zulassen oder nicht.

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

Siehe folgendes Beispiel:

  • name wird entfernt, sofern vorhanden.
  • age wird mit dem Wert 25 (int) hinzugefügt, falls nicht vorhanden. Wenn vorhanden, wird age auf den Wert 25 aktualisiert.
  • eye color wird hinzugefügt oder auf den Wert green aktualisiert.
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

Siehe folgendes Beispiel:

  • full name wird hinzugefügt oder auf den einzelnen Wert Morena Baccarin aktualisiert.
  • ping-Parameter werden hinzugefügt oder durch 35, 16, 87 und 240 ersetzt.
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

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 name mit dem Wert Morena Baccarin hinzuzufügen oder zu ersetzen.
  • Ruft NavigateTo auf, um die Navigation zur neuen URL auszulösen.
Navigation.NavigateTo(
    Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));

Benutzerinteraktion mit <Navigating>-Inhalt

Die Router-Komponente zeigt dem Benutzer, dass ein Seitenübergang erfolgt.

Fügen Sie oben in der App-Komponente (App.razor) eine @using-Anweisung für den Microsoft.AspNetCore.Components.Routing-Namespace hinzu:

@using Microsoft.AspNetCore.Components.Routing

Fügen Sie der Komponente ein <Navigating>-Tag mit Markup für die Anzeige während Seitenübergangsereignissen hinzu. Weitere Informationen finden Sie unter Navigating (in der API-Dokumentation).

Im Routerelementinhalt (<Router>...</Router>) der App-Komponente (App.razor):

<Navigating>
    <p>Loading the requested page&hellip;</p>
</Navigating>

Ein Beispiel, in dem die Navigating-Eigenschaft verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Behandeln von asynchronen Navigationsereignissen mit OnNavigateAsync

Die Router-Komponente unterstützt ein OnNavigateAsync-Feature. Der OnNavigateAsync-Handler wird aufgerufen, wenn der Benutzer:

  • zum ersten Mal eine Route benutzt, indem er direkt über den Browser dorthin navigiert.
  • Zu einer neuen Route mithilfe eines Links oder eines NavigationManager.NavigateTo-Aufrufs navigiert.

In der App-Komponente (App.razor):

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}

Ein Beispiel, in dem OnNavigateAsync verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Beim Prerendering auf dem Server in einer Blazor Server-App oder gehosteten Blazor WebAssembly-App wird OnNavigateAsynczweimal ausgeführt:

  • Einmal, wenn die angeforderte Endpunktkomponente zuerst statisch als Teil der Seite gerendert wird.
  • Ein zweites Mal, wenn der Browser die Endpunktkomponente rendert.

Die App-Komponente kann das NavigationContext-Objekt zur Verwendung in OnAfterRender{Async} speichern, um zu verhindern, dass Entwicklercode in OnNavigateAsync zweimal ausgeführt wird. Dort kann das firstRender-Objekt auch überprüft werden. Weitere Informationen finden Sie unter Voarabrendering mit JavaScript-Interop im Artikel Blazor-Lebenszyklus.

Verarbeiten von Abbrüchen in OnNavigateAsync

Das NavigationContext-Objekt, das an den OnNavigateAsync-Rückruf übergeben wird, enthält ein CancellationToken, das beim Auftreten eines neuen Navigationsereignisses festgelegt wird. Der OnNavigateAsync-Rückruf muss ausgelöst werden, wenn dieses Abbruchtoken festgelegt wird, um zu vermeiden, dass der OnNavigateAsync-Rückruf für eine veraltete Navigation weiterhin ausgeführt wird.

Wenn ein Benutzer zu einem Endpunkt navigiert, aber dann sofort zu einem neuen Endpunkt wechselt, sollte die App den OnNavigateAsync-Rückruf für den ersten Endpunkt nicht weiter ausführen.

Für das folgende App-Komponentenbeispiel gilt Folgendes:

  • Das Abbruchtoken wird im Aufruf von PostAsJsonAsync übergeben, der den POST-Vorgang abbrechen kann, wenn der Benutzer vom /about-Endpunkt weg navigiert.
  • Das Abbruchtoken wird während eines Produktvorabrufs festgelegt, wenn der Benutzer vom /store-Endpunkt weg navigiert.

App.razor:

@inject HttpClient Http
@inject ProductCatalog Products

<Router AppAssembly="@typeof(App).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext context)
    {
        if (context.Path == "/about") 
        {
            var stats = new Stats { Page = "/about" };
            await Http.PostAsJsonAsync("api/visited", stats, 
                context.CancellationToken);
        }
        else if (context.Path == "/store")
        {
            var productIds = [345, 789, 135, 689];

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}

Hinweis

Wenn der Rückruf nicht ausgelöst wird, wenn das Abbruchtoken in NavigationContext abgebrochen wird, kann dies zu unbeabsichtigtem Verhalten führen, z. B. zum Rendern einer Komponente aus einer vorherigen Navigation.

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.

Hinweis

Die NavMenu-Komponente (NavMenu.razor) wird im Ordner Shared einer App bereitgestellt, die aus den Blazor-Projektvorlagen generiert wurde.

Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:

Im vorherigen Beispiel entspricht HomeNavLinkhref="" der Home-URL und empfängt nur die CSS-Klasse active über die Standardbasispfad-URL der App (z. B. https://localhost:5001/). Die zweite NavLink-Komponente empfängt die active-Klasse, wenn der Benutzer eine beliebige URL mit einem component-Präfix aufruft (z. B. https://localhost:5001/component und https://localhost:5001/component/another-segment).

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 = 0; c < 10; c++)
{
    var current = c;
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @current
        </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(0,10))
{
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @c
        </NavLink>
    </li>
}

Integration von ASP.NET Core-Endpunktrouting

Dieser Abschnitt gilt nur für Blazor Server-Apps.

Blazor Server ist in das ASP.NET Core-Endpunktrouting integriert. Eine ASP.NET Core-App ist so konfiguriert, dass sie eingehende Verbindungen für interaktive Komponenten mit MapBlazorHub in Program.cs akzeptiert:

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

Die typische Konfiguration ist die Weiterleitung aller Anforderungen an eine Razor-Seite, die als Host für den serverseitigen Teil der Blazor Server-App fungiert. Gemäß der Konvention wird die Hostseite in der Regel im Ordner Pages der App mit _Host.cshtml benannt.

Die in der Hostdatei angegebene Route wird als Fallbackroute bezeichnet, da sie mit einer niedrigen Priorität bei der Routenanpassung arbeitet. Die Ausweichroute wird verwendet, wenn andere Routen nicht passen. Dadurch kann die App andere Controller und Seiten verwenden, ohne das Komponentenrouting in der Blazor Server-App zu beeinträchtigen.

Routenvorlagen

Die Router-Komponente ermöglicht das Routing an Razor-Komponenten in einer Blazor-App. Die Router-Komponente wird in der App-Komponente von Blazor-Apps verwendet.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

Wenn eine Razor-Komponente (.razor) mit einer @page-Anweisung kompiliert wird, wird für die generierte Komponentenklasse ein RouteAttribute-Objekt bereitgestellt, das die Routenvorlage der Komponente angibt.

Wenn die App gestartet wird, wird die Assembly gescannt, die als AppAssembly-Objekt des Routers angegeben wurde, um Routeninformationen für die Komponenten der App zu erfassen, die über ein RouteAttribute-Objekt verfügen.

Zur Laufzeit führt die RouteView-Komponente Folgendes aus:

  • Sie empfängt das RouteData-Objekt vom Router-Objekt zusammen mit den Routenparametern.
  • Sie rendert die angegebene Komponente mit deren Layout, einschließlich aller weiteren geschachtelten Layouts.

Optional können Sie einen DefaultLayout-Parameter mit einer Layoutklasse für Komponenten angeben, die kein Layout mit der @layout-Anweisung festlegen. Die Blazor-Projektvorlagen des Frameworks geben die MainLayout-Komponente (Shared/MainLayout.razor) als Standardlayout der App an. Weitere Informationen zu Layouts finden Sie unter Blazor-Layouts in ASP.NET Core.

Komponenten unterstützen mehrere Routenvorlagen mithilfe mehrerer @page-Anweisungen. Die folgende Beispielkomponente lädt Anforderungen für /blazor-route und /different-blazor-route.

Pages/BlazorRoute.razor:

@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

Wichtig

Damit URLs korrekt aufgelöst werden können, muss die Anwendung ein <base>-Tag in ihrer wwwroot/index.html-Datei (Blazor WebAssembly) oder Pages/_Host.cshtml-Datei (Blazor Server) mit dem im href-Attribut angegebenen App-Basispfad enthalten. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor in ASP.NET Core.

Router interagiert nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Alternativ zur Angabe der Routenvorlage als Zeichenfolgenliteral mit der Anweisung @page können konstantenbasierte Routenvorlagen mit der @attribute-Anweisung angegeben werden.

Im folgenden Beispiel wird die Anweisung @page in einer Komponente durch die Anweisung @attribute und die konstantenbasierte Routenvorlage in Constants.CounterRoute ersetzt, die an anderer Stelle in der App auf /counter festgelegt wird:

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

Bereitstellen von benutzerdefiniertem Inhalt, wenn kein Inhalt gefunden wurde

Die Router-Komponente ermöglicht es der App, benutzerdefinierte Inhalte anzugeben, wenn für die angeforderte Route keine Inhalte gefunden werden.

In der App-Komponente können Sie benutzerdefinierten Inhalt in der Router-Vorlage der NotFound-Komponente festlegen.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <h1>Sorry</h1>
        <p>Sorry, there's nothing at this address.</p> b
    </NotFound>
</Router>

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Beliebige Elemente werden als Inhalt der <NotFound>-Tags unterstützt, z. B. andere interaktive Komponenten. Informationen zum Anwenden eines Standardlayouts auf NotFound-Inhalte finden Sie unter Blazor-Layouts in ASP.NET Core.

Weiterleiten an Komponenten aus mehreren Assemblys

Verwenden Sie den AdditionalAssemblies-Parameter, um zusätzliche Assemblys anzugeben, die die Router-Komponente bei der Suche nach für das Routing geeigneten Komponenten beachten soll. Zusätzliche Assemblys werden neben der für AppAssembly angegebenen Assembly gescannt. Im folgenden Beispiel ist Component1 eine für das Routing geeignete Komponente, die in einer Komponentenklassenbibliothek definiert ist, auf die verwiesen wird. Im folgenden AdditionalAssemblies-Beispiel wird Routing für Component1 unterstützt.

App.razor:

<Router
    AppAssembly="@typeof(Program).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Routenparameter

Der Router verwendet Routenparameter, um die entsprechenden Komponentenparameter mit demselben Namen aufzufüllen. Bei den Routenparameternamen muss die Groß- und Kleinschreibung nicht berücksichtigt werden. Im folgenden Beispiel weist der Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn eine Anforderung für /route-parameter-1/amazing erfolgt, wird der Inhalt der <h1>-Tags als Blazor is amazing! gerendert.

Pages/RouteParameter1.razor:

@page "/route-parameter-1/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }
}

Optionale Parameter werden unterstützt. Im folgenden Beispiel weist der optionale Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn das Segment nicht vorhanden ist, wird der Wert von Text auf fantastic festgelegt.

Pages/RouteParameter2.razor:

@page "/route-parameter-2/{text?}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

Verwenden Sie OnParametersSet anstelle von OnInitialized{Async}, um die App-Navigation zur gleichen Komponente mit einem anderen optionalen Parameterwert zuzulassen. Verwenden Sie auf der Grundlage des vorangehenden Beispiels OnParametersSet, wenn der Benutzer in der Lage sein soll, von /route-parameter-2 zu /route-parameter-2/amazing oder von /route-parameter-2/amazing zu /route-parameter-2 zu navigieren:

protected override void OnParametersSet()
{
    Text = Text ?? "fantastic";
}

Hinweis

Routenparameter funktionieren nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Routeneinschränkungen

Eine Routeneinschränkung erzwingt die Typübereinstimmung in einem Routensegment zu einer Komponente.

Im folgenden Beispiel stimmt die Route zur User-Komponente nur überein, wenn:

  • ein Id-Routensegment in der Anforderungs-URL vorhanden ist.
  • das Id-Segment ein Integer (int) ist.

Pages/User.razor:

@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Hinweis

Routeneinschränkungen funktionieren nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Die in der folgenden Tabelle aufgeführten Routeneinschränkungen sind verfügbar. Informationen zu den Routeneinschränkungen der invarianten Kultur finden Sie in der Warnung unter der Tabelle.

Constraint Beispiel Beispiele für Übereinstimmungen Invariante
Kultur
Übereinstimmend
bool {active:bool} true, FALSE Nein
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Ja
decimal {price:decimal} 49.99, -1,000.01 Ja
double {weight:double} 1.234, -1,001.01e8 Ja
float {weight:float} 1.234, -1,001.01e8 Ja
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Nein
int {id:int} 123456789, -123456789 Ja
long {ticks:long} 123456789, -123456789 Ja

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.

Routeneinschränkungen funktionieren auch mit optionalen Parametern. Im folgenden Beispiel ist Id erforderlich, während Option ein optionaler boolescher Routenparameter ist.

Pages/User.razor:

@page "/user/{Id:int}/{Option:bool?}"

<p>
    Id: @Id
</p>

<p>
    Option: @Option
</p>

@code {
    [Parameter]
    public int Id { get; set; }

    [Parameter]
    public bool Option { get; set; }
}

Routing mit URLs, die Punkte enthalten

Wenn das letzte Segment einer Anforderungs-URL einen Punkt (.) enthält, wird bei gehosteten Blazor WebAssembly- und Blazor Server-Apps von der serverseitigen Standardvorlage für Routen davon ausgegangen, dass eine Datei angefordert wird. Beispielsweise wird die URL https://localhost.com:5001/example/some.thing vom Router als Anforderung für eine Datei mit dem Namen some.thing interpretiert. Ohne zusätzliche Konfiguration gibt eine App die Antwort 404 – Nicht gefunden zurück, wenn some.thing an eine Komponente mit einer @page-Anweisung weiterleiten sollte und some.thing ein Routenparameterwert ist. Wenn eine Route mit mindestens einem Parameter verwendet werden soll, der einen Punkt enthält, muss die Route von der App mit einer benutzerdefinierten Vorlage konfiguriert werden.

Sehen Sie sich z. B. die folgende Example-Komponente an, die einen Routenparameter aus dem letzten Segment der URL empfangen kann.

Pages/Example.razor:

@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string Param { get; set; }
}

Wenn Sie der Server-App einer gehosteten Blazor WebAssembly-Lösung erlauben möchten, dass sie die Anforderung mit einem Punkt im param-Routenparameter weiterleitet, fügen Sie eine Ausweichdatei-Routenvorlage mit dem optionale Parameter in Startup.Configure hinzu.

Startup.cs:

endpoints.MapFallbackToFile("/example/{param?}", "index.html");

Fügen Sie eine Ausweichdatei-Routenvorlage hinzu, wobei sich der optionale Parameter in Startup.Configure befindet, um eine Blazor Server-App so zu konfigurieren, dass die Anforderung mit einem Punkt im param-Routenparameter weiterleitet wird.

Startup.cs:

endpoints.MapFallbackToPage("/example/{param?}", "/_Host");

Weitere Informationen finden Sie unter Routing in ASP.NET Core.

Catch-All-Routenparameter

Catch-All-Routenparameter, die Pfade über mehrere Ordnergrenzen hinweg erfassen, werden in Komponenten unterstützt.

Für Catch-All-Routenparameter gilt:

  • Sie müssen so benannt werden, dass sie dem Routensegmentnamen entsprechen. Die Groß-/Kleinschreibung muss bei der Benennung nicht beachtet werden.
  • Ein string-Typ. Im Framework steht keine automatische Übertragung zur Verfügung.
  • Am Ende der URL.

Pages/CatchAll.razor:

@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string PageRoute { get; set; }
}

Bei der URL /catch-all/this/is/a/test mit der Routenvorlage /catch-all/{*pageRoute} wird der Wert für PageRoute auf this/is/a/test festgelegt.

Schrägstriche und Segmente des erfassten Pfads werden decodiert. Bei der Routenvorlage /catch-all/{*pageRoute} hält die URL /catch-all/this/is/a%2Ftest%2Athis/is/a/test* an.

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.

Member Beschreibung
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 href-Attribut im <base>-Element des Dokuments in wwwroot/index.html (Blazor WebAssembly) oder Pages/_Host.cshtml (Blazor Server).
NavigateTo Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert true:
  • Clientseitiges Routing wird umgangen.
  • Der Browser ist gezwungen, die neue Seite vom Server zu laden, unabhängig davon, ob der URI normalerweise vom clientseitigen Router verarbeitet wird oder nicht.
LocationChanged Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat.
ToAbsoluteUri Konvertiert einen relativen URI in einen absoluten URI.
ToBaseRelativePath Wenn ein Basis-URI (z. B. ein URI, der zuvor von BaseUri zurückgegeben wurde) vorhanden ist, wird ein absoluter URI in einen URI relativ zum Basis-URI-Präfix konvertiert.

Für das LocationChanged-Ereignis bietet LocationChangedEventArgs die folgenden Informationen zu Navigationsereignissen:

Die folgende Komponente führt folgende Aktionen aus:

  • Sie navigiert zur Counter-Komponente der App (Pages/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, wenn Dispose vom 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:5001/counter

Pages/Navigate.razor:

@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code 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 Beseitigung von Komponenten finden Sie unter Lebenszyklus von Razor-Komponenten in ASP.NET Core.

Abfragezeichenfolgen und Analysieren von Parametern

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.

Benutzerinteraktion mit <Navigating>-Inhalt

Die Router-Komponente zeigt dem Benutzer, dass ein Seitenübergang erfolgt.

Fügen Sie oben in der App-Komponente (App.razor) eine @using-Anweisung für den Microsoft.AspNetCore.Components.Routing-Namespace hinzu:

@using Microsoft.AspNetCore.Components.Routing

Fügen Sie der Komponente ein <Navigating>-Tag mit Markup für die Anzeige während Seitenübergangsereignissen hinzu. Weitere Informationen finden Sie unter Navigating (in der API-Dokumentation).

Im Routerelementinhalt (<Router>...</Router>) der App-Komponente (App.razor):

<Navigating>
    <p>Loading the requested page&hellip;</p>
</Navigating>

Ein Beispiel, in dem die Navigating-Eigenschaft verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Behandeln von asynchronen Navigationsereignissen mit OnNavigateAsync

Die Router-Komponente unterstützt ein OnNavigateAsync-Feature. Der OnNavigateAsync-Handler wird aufgerufen, wenn der Benutzer:

  • zum ersten Mal eine Route benutzt, indem er direkt über den Browser dorthin navigiert.
  • Zu einer neuen Route mithilfe eines Links oder eines NavigationManager.NavigateTo-Aufrufs navigiert.

In der App-Komponente (App.razor):

<Router AppAssembly="@typeof(Program).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Ein Beispiel, in dem OnNavigateAsync verwendet wird, finden Sie unter Verzögertes Laden von Assemblys in Blazor WebAssembly in ASP.NET Core.

Beim Prerendering auf dem Server in einer Blazor Server-App oder gehosteten Blazor WebAssembly-App wird OnNavigateAsynczweimal ausgeführt:

  • Einmal, wenn die angeforderte Endpunktkomponente zuerst statisch als Teil der Seite gerendert wird.
  • Ein zweites Mal, wenn der Browser die Endpunktkomponente rendert.

Die App-Komponente kann das NavigationContext-Objekt zur Verwendung in OnAfterRender{Async} speichern, um zu verhindern, dass Entwicklercode in OnNavigateAsync zweimal ausgeführt wird. Dort kann das firstRender-Objekt auch überprüft werden. Weitere Informationen finden Sie unter Voarabrendering mit JavaScript-Interop im Artikel Blazor-Lebenszyklus.

Verarbeiten von Abbrüchen in OnNavigateAsync

Das NavigationContext-Objekt, das an den OnNavigateAsync-Rückruf übergeben wird, enthält ein CancellationToken, das beim Auftreten eines neuen Navigationsereignisses festgelegt wird. Der OnNavigateAsync-Rückruf muss ausgelöst werden, wenn dieses Abbruchtoken festgelegt wird, um zu vermeiden, dass der OnNavigateAsync-Rückruf für eine veraltete Navigation weiterhin ausgeführt wird.

Wenn ein Benutzer zu einem Endpunkt navigiert, aber dann sofort zu einem neuen Endpunkt wechselt, sollte die App den OnNavigateAsync-Rückruf für den ersten Endpunkt nicht weiter ausführen.

Für das folgende App-Komponentenbeispiel gilt Folgendes:

  • Das Abbruchtoken wird im Aufruf von PostAsJsonAsync übergeben, der den POST-Vorgang abbrechen kann, wenn der Benutzer vom /about-Endpunkt weg navigiert.
  • Das Abbruchtoken wird während eines Produktvorabrufs festgelegt, wenn der Benutzer vom /store-Endpunkt weg navigiert.

App.razor:

@inject HttpClient Http
@inject ProductCatalog Products

<Router AppAssembly="@typeof(Program).Assembly" 
    OnNavigateAsync="@OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext context)
    {
        if (context.Path == "/about") 
        {
            var stats = new Stats { Page = "/about" };
            await Http.PostAsJsonAsync("api/visited", stats, 
                context.CancellationToken);
        }
        else if (context.Path == "/store")
        {
            var productIds = [345, 789, 135, 689];

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}

Hinweis

Seit der Veröffentlichung von ASP.NET Core 5.0.1 und allen weiteren 5.x-Releases enthält die Router-Komponente den PreferExactMatches-Parameter, der auf @true festgelegt ist. Weitere Informationen finden Sie unter Migrieren von ASP.NET Core 3.1 zu 5.0.

Hinweis

Wenn der Rückruf nicht ausgelöst wird, wenn das Abbruchtoken in NavigationContext abgebrochen wird, kann dies zu unbeabsichtigtem Verhalten führen, z. B. zum Rendern einer Komponente aus einer vorherigen Navigation.

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.

Hinweis

Die NavMenu-Komponente (NavMenu.razor) wird im Ordner Shared einer App bereitgestellt, die aus den Blazor-Projektvorlagen generiert wurde.

Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:

Im vorherigen Beispiel entspricht HomeNavLinkhref="" der Home-URL und empfängt nur die CSS-Klasse active über die Standardbasispfad-URL der App (z. B. https://localhost:5001/). Die zweite NavLink-Komponente empfängt die active-Klasse, wenn der Benutzer eine beliebige URL mit einem component-Präfix aufruft (z. B. https://localhost:5001/component und https://localhost:5001/component/another-segment).

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 = 0; c < 10; c++)
{
    var current = c;
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @current
        </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(0,10))
{
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @c
        </NavLink>
    </li>
}

Integration von ASP.NET Core-Endpunktrouting

Dieser Abschnitt gilt nur für Blazor Server-Apps.

Blazor Server ist in das ASP.NET Core-Endpunktrouting integriert. Eine ASP.NET Core-App ist so konfiguriert, dass sie eingehende Verbindungen für interaktive Komponenten mit MapBlazorHub in Startup.Configure akzeptiert.

Startup.cs:

using Microsoft.AspNetCore.Builder;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }
}

Die typische Konfiguration ist die Weiterleitung aller Anforderungen an eine Razor-Seite, die als Host für den serverseitigen Teil der Blazor Server-App fungiert. Gemäß der Konvention wird die Hostseite in der Regel im Ordner Pages der App mit _Host.cshtml benannt.

Die in der Hostdatei angegebene Route wird als Fallbackroute bezeichnet, da sie mit einer niedrigen Priorität bei der Routenanpassung arbeitet. Die Ausweichroute wird verwendet, wenn andere Routen nicht passen. Dadurch kann die App andere Controller und Seiten verwenden, ohne das Komponentenrouting in der Blazor Server-App zu beeinträchtigen.

Routenvorlagen

Die Router-Komponente ermöglicht das Routing an Razor-Komponenten in einer Blazor-App. Die Router-Komponente wird in der App-Komponente von Blazor-Apps verwendet.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <p>Sorry, there's nothing at this address.</p>
    </NotFound>
</Router>

Wenn eine Razor-Komponente (.razor) mit einer @page-Anweisung kompiliert wird, wird für die generierte Komponentenklasse ein RouteAttribute-Objekt bereitgestellt, das die Routenvorlage der Komponente angibt.

Wenn die App gestartet wird, wird die Assembly gescannt, die als AppAssembly-Objekt des Routers angegeben wurde, um Routeninformationen für die Komponenten der App zu erfassen, die über ein RouteAttribute-Objekt verfügen.

Zur Laufzeit führt die RouteView-Komponente Folgendes aus:

  • Sie empfängt das RouteData-Objekt vom Router-Objekt zusammen mit den Routenparametern.
  • Sie rendert die angegebene Komponente mit deren Layout, einschließlich aller weiteren geschachtelten Layouts.

Optional können Sie einen DefaultLayout-Parameter mit einer Layoutklasse für Komponenten angeben, die kein Layout mit der @layout-Anweisung festlegen. Die Blazor-Projektvorlagen des Frameworks geben die MainLayout-Komponente (Shared/MainLayout.razor) als Standardlayout der App an. Weitere Informationen zu Layouts finden Sie unter Blazor-Layouts in ASP.NET Core.

Komponenten unterstützen mehrere Routenvorlagen mithilfe mehrerer @page-Anweisungen. Die folgende Beispielkomponente lädt Anforderungen für /blazor-route und /different-blazor-route.

Pages/BlazorRoute.razor:

@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

Wichtig

Damit URLs korrekt aufgelöst werden können, muss die Anwendung ein <base>-Tag in ihrer wwwroot/index.html-Datei (Blazor WebAssembly) oder Pages/_Host.cshtml-Datei (Blazor Server) mit dem im href-Attribut angegebenen App-Basispfad enthalten. Weitere Informationen finden Sie unter Hosten und Bereitstellen von Blazor in ASP.NET Core.

Router interagiert nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Alternativ zur Angabe der Routenvorlage als Zeichenfolgenliteral mit der Anweisung @page können konstantenbasierte Routenvorlagen mit der @attribute-Anweisung angegeben werden.

Im folgenden Beispiel wird die Anweisung @page in einer Komponente durch die Anweisung @attribute und die konstantenbasierte Routenvorlage in Constants.CounterRoute ersetzt, die an anderer Stelle in der App auf /counter festgelegt wird:

- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]

Bereitstellen von benutzerdefiniertem Inhalt, wenn kein Inhalt gefunden wurde

Die Router-Komponente ermöglicht es der App, benutzerdefinierte Inhalte anzugeben, wenn für die angeforderte Route keine Inhalte gefunden werden.

In der App-Komponente können Sie benutzerdefinierten Inhalt in der Router-Vorlage der NotFound-Komponente festlegen.

App.razor:

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <h1>Sorry</h1>
        <p>Sorry, there's nothing at this address.</p> b
    </NotFound>
</Router>

Beliebige Elemente werden als Inhalt der <NotFound>-Tags unterstützt, z. B. andere interaktive Komponenten. Informationen zum Anwenden eines Standardlayouts auf NotFound-Inhalte finden Sie unter Blazor-Layouts in ASP.NET Core.

Weiterleiten an Komponenten aus mehreren Assemblys

Verwenden Sie den AdditionalAssemblies-Parameter, um zusätzliche Assemblys anzugeben, die die Router-Komponente bei der Suche nach für das Routing geeigneten Komponenten beachten soll. Zusätzliche Assemblys werden neben der für AppAssembly angegebenen Assembly gescannt. Im folgenden Beispiel ist Component1 eine für das Routing geeignete Komponente, die in einer Komponentenklassenbibliothek definiert ist, auf die verwiesen wird. Im folgenden AdditionalAssemblies-Beispiel wird Routing für Component1 unterstützt.

App.razor:

<Router
    AppAssembly="@typeof(Program).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

Routenparameter

Der Router verwendet Routenparameter, um die entsprechenden Komponentenparameter mit demselben Namen aufzufüllen. Bei den Routenparameternamen muss die Groß- und Kleinschreibung nicht berücksichtigt werden. Im folgenden Beispiel weist der Parameter text den Wert des Routensegments der Eigenschaft Text der Komponente zu. Wenn eine Anforderung für /route-parameter-1/amazing erfolgt, wird der Inhalt der <h1>-Tags als Blazor is amazing! gerendert.

Pages/RouteParameter1.razor:

@page "/route-parameter-1/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }
}

Optionale Parameter werden nicht unterstützt. Im folgenden Beispiel werden zwei @page-Anweisungen angewendet. Die erste Anweisung ermöglicht die Navigation zur Komponente ohne einen Parameter. Die zweite Direktive weist der Text-Eigenschaft der Komponente den Wert für die {text}-Routenparameter zu.

Pages/RouteParameter2.razor:

@page "/route-parameter-2"
@page "/route-parameter-2/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

Verwenden Sie OnParametersSet anstelle von OnInitialized{Async}, um die App-Navigation zur gleichen Komponente mit einem anderen optionalen Parameterwert zuzulassen. Verwenden Sie auf der Grundlage des vorangehenden Beispiels OnParametersSet, wenn der Benutzer in der Lage sein soll, von /route-parameter-2 zu /route-parameter-2/amazing oder von /route-parameter-2/amazing zu /route-parameter-2 zu navigieren:

protected override void OnParametersSet()
{
    Text = Text ?? "fantastic";
}

Hinweis

Routenparameter funktionieren nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Routeneinschränkungen

Eine Routeneinschränkung erzwingt die Typübereinstimmung in einem Routensegment zu einer Komponente.

Im folgenden Beispiel stimmt die Route zur User-Komponente nur überein, wenn:

  • ein Id-Routensegment in der Anforderungs-URL vorhanden ist.
  • das Id-Segment ein Integer (int) ist.

Pages/User.razor:

@page "/user/{Id:int}"

<h1>User Id: @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Hinweis

Routeneinschränkungen funktionieren nicht mit Abfragezeichenfolgenwerten. Informationen zur Verwendung von Abfragezeichenfolgen finden Sie im Abschnitt zu Abfragezeichenfolge und Analyseparametern.

Die in der folgenden Tabelle aufgeführten Routeneinschränkungen sind verfügbar. Informationen zu den Routeneinschränkungen der invarianten Kultur finden Sie in der Warnung unter der Tabelle.

Constraint Beispiel Beispiele für Übereinstimmungen Invariante
Kultur
Übereinstimmend
bool {active:bool} true, FALSE Nein
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Ja
decimal {price:decimal} 49.99, -1,000.01 Ja
double {weight:double} 1.234, -1,001.01e8 Ja
float {weight:float} 1.234, -1,001.01e8 Ja
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} Nein
int {id:int} 123456789, -123456789 Ja
long {ticks:long} 123456789, -123456789 Ja

Warnung

Für Routeneinschränkungen, mit denen die URL überprüft wird und die in den CLR-Typ umgewandelt werden (beispielsweise int oder DateTime), wird immer die invariante Kultur verwendet. Diese Einschränkungen setzen voraus, dass die URL nicht lokalisierbar ist.

Routing mit URLs, die Punkte enthalten

Wenn das letzte Segment einer Anforderungs-URL einen Punkt (.) enthält, wird bei gehosteten Blazor WebAssembly- und Blazor Server-Apps von der serverseitigen Standardvorlage für Routen davon ausgegangen, dass eine Datei angefordert wird. Beispielsweise wird die URL https://localhost.com:5001/example/some.thing vom Router als Anforderung für eine Datei mit dem Namen some.thing interpretiert. Ohne zusätzliche Konfiguration gibt eine App die Antwort 404 – Nicht gefunden zurück, wenn some.thing an eine Komponente mit einer @page-Anweisung weiterleiten sollte und some.thing ein Routenparameterwert ist. Wenn eine Route mit mindestens einem Parameter verwendet werden soll, der einen Punkt enthält, muss die Route von der App mit einer benutzerdefinierten Vorlage konfiguriert werden.

Sehen Sie sich z. B. die folgende Example-Komponente an, die einen Routenparameter aus dem letzten Segment der URL empfangen kann.

Pages/Example.razor:

@page "/example"
@page "/example/{param}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string Param { get; set; }
}

Wenn Sie der Server-App einer gehosteten Blazor WebAssembly-Lösung erlauben möchten, dass sie die Anforderung mit einem Punkt im param-Routenparameter weiterleitet, fügen Sie eine Ausweichdatei-Routenvorlage mit dem optionale Parameter in Startup.Configure hinzu.

Startup.cs:

endpoints.MapFallbackToFile("/example/{param?}", "index.html");

Fügen Sie eine Ausweichdatei-Routenvorlage hinzu, wobei sich der optionale Parameter in Startup.Configure befindet, um eine Blazor Server-App so zu konfigurieren, dass die Anforderung mit einem Punkt im param-Routenparameter weiterleitet wird.

Startup.cs:

endpoints.MapFallbackToPage("/example/{param?}", "/_Host");

Weitere Informationen finden Sie unter Routing in ASP.NET Core.

Catch-All-Routenparameter

Catch-All-Routenparameter werden ab ASP.NET Core 5.0 unterstützt. Weitere Informationen finden Sie im Artikel zur 5.0-Version.

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.

Member Beschreibung
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 href-Attribut im <base>-Element des Dokuments in wwwroot/index.html (Blazor WebAssembly) oder Pages/_Host.cshtml (Blazor Server).
NavigateTo Navigiert zum angegebenen URI. Bei forceLoad lautet der Wert true:
  • Clientseitiges Routing wird umgangen.
  • Der Browser ist gezwungen, die neue Seite vom Server zu laden, unabhängig davon, ob der URI normalerweise vom clientseitigen Router verarbeitet wird oder nicht.
LocationChanged Ein Ereignis, das ausgelöst wird, wenn sich die Navigationsposition geändert hat.
ToAbsoluteUri Konvertiert einen relativen URI in einen absoluten URI.
ToBaseRelativePath Wenn ein Basis-URI (z. B. ein URI, der zuvor von BaseUri zurückgegeben wurde) vorhanden ist, wird ein absoluter URI in einen URI relativ zum Basis-URI-Präfix konvertiert.

Für das LocationChanged-Ereignis bietet LocationChangedEventArgs die folgenden Informationen zu Navigationsereignissen:

Die folgende Komponente führt folgende Aktionen aus:

  • Sie navigiert zur Counter-Komponente der App (Pages/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, wenn Dispose vom 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:5001/counter

Pages/Navigate.razor:

@page "/navigate"
@using Microsoft.Extensions.Logging 
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<h1>Navigate in component code 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 Beseitigung von Komponenten finden Sie unter Lebenszyklus von Razor-Komponenten in ASP.NET Core.

Abfragezeichenfolgen und Analysieren von Parametern

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:

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.

Hinweis

Die NavMenu-Komponente (NavMenu.razor) wird im Ordner Shared einer App bereitgestellt, die aus den Blazor-Projektvorlagen generiert wurde.

Es gibt zwei NavLinkMatch-Optionen, die Sie dem Match-Attribut des <NavLink>-Elements zuweisen können:

Im vorherigen Beispiel entspricht HomeNavLinkhref="" der Home-URL und empfängt nur die CSS-Klasse active über die Standardbasispfad-URL der App (z. B. https://localhost:5001/). Die zweite NavLink-Komponente empfängt die active-Klasse, wenn der Benutzer eine beliebige URL mit einem component-Präfix aufruft (z. B. https://localhost:5001/component und https://localhost:5001/component/another-segment).

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 = 0; c < 10; c++)
{
    var current = c;
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @current
        </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(0,10))
{
    <li ...>
        <NavLink ... href="@c">
            <span ...></span> @c
        </NavLink>
    </li>
}

Integration von ASP.NET Core-Endpunktrouting

Dieser Abschnitt gilt nur für Blazor Server-Apps.

Blazor Server ist in das ASP.NET Core-Endpunktrouting integriert. Eine ASP.NET Core-App ist so konfiguriert, dass sie eingehende Verbindungen für interaktive Komponenten mit MapBlazorHub in Startup.Configure akzeptiert.

Startup.cs:

using Microsoft.AspNetCore.Builder;

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToPage("/_Host");
        });
    }
}

Die typische Konfiguration ist die Weiterleitung aller Anforderungen an eine Razor-Seite, die als Host für den serverseitigen Teil der Blazor Server-App fungiert. Gemäß der Konvention wird die Hostseite in der Regel im Ordner Pages der App mit _Host.cshtml benannt.

Die in der Hostdatei angegebene Route wird als Fallbackroute bezeichnet, da sie mit einer niedrigen Priorität bei der Routenanpassung arbeitet. Die Ausweichroute wird verwendet, wenn andere Routen nicht passen. Dadurch kann die App andere Controller und Seiten verwenden, ohne das Komponentenrouting in der Blazor Server-App zu beeinträchtigen.