Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga / Notatka
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualną wersją, zobacz artykuł w wersji .NET 10.
W tym artykule wyjaśniono, jak wyzwalać i obsługiwać nawigację między stronami w programie Blazor. Użytkownicy mogą nawigować między różnymi stronami przy użyciu zwykłych linków HTML, a Blazor usprawnia nawigację w aplikacji, aby uniknąć ponownego ładowania pełnej strony i zapewnić płynniejsze działanie. NavLink Użyj składnika , aby utworzyć linki nawigacji, które automatycznie stosują styl, gdy link pasuje do bieżącej strony. W przypadku programowego zarządzania nawigacją i identyfikatorem URI w kodzie języka C# użyj usługi NavigationManager.
W tym artykule wyjaśniono, jak wyzwalać i obsługiwać nawigację między stronami w programie Blazor. NavLink Użyj składnika , aby utworzyć linki nawigacji, które automatycznie stosują styl, gdy link pasuje do bieżącej strony. W przypadku programowego zarządzania nawigacją i identyfikatorem URI w kodzie języka C# użyj usługi NavigationManager.
Ważne
Przykłady kodu w tym artykule pokazują metody wywoływane na Navigation, który jest wstrzykiwany jako NavigationManager w klasach i komponentach.
NavLink komponent
NavLink Podczas tworzenia linków nawigacyjnych użyj składnika zamiast elementów hiperłącza HTML (<a>).
NavLink Składnik zachowuje się jak <a> element, z wyjątkiem, że przełącza klasę active CSS w zależności od tego, czy jego href pasuje do bieżącego adresu URL. Klasa active pomaga użytkownikowi zrozumieć, która strona jest aktywną stroną wśród wyświetlanych linków nawigacji. Opcjonalnie przypisz do NavLink.ActiveClass nazwę klasy CSS, aby zastosować niestandardową klasę CSS do renderowanego linku, gdy bieżąca trasa jest zgodna z href.
W składniku NavMenu (NavMenu.razor) aplikacji Blazor utworzonej na podstawie szablonu projektu Blazor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
</NavLink>
</div>
W poprzednim przykładzie HomeNavLinkhref="" pasuje do adresu URL strony głównej i otrzymuje tylko klasę active CSS na domyślnej ścieżce podstawowej aplikacji (/). Drugi NavLink otrzymuje klasę active, gdy użytkownik odwiedzi Counter komponent pod adresem /counter.
Istnieją dwie NavLinkMatch opcje, które można przypisać do Match atrybutu <NavLink> elementu:
-
NavLinkMatch.All: NavLink jest aktywna, gdy jest zgodna z bieżącym adresem URL, ignorując ciąg zapytania i fragment. Aby dołączyć dopasowanie do ciągu/fragmentu zapytania, użyj przełącznika ustawionego
Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragmentAppContextnatrue. - NavLinkMatch.Prefix (ustawienie domyślne): NavLink jest aktywny, gdy pasuje do dowolnego prefiksu bieżącego adresu URL.
Aby wdrożyć niestandardową logikę dopasowania, utwórz podklasę z NavLink i zastąp jej metodę ShouldMatch. Zwróć true z metody, gdy chcesz zastosować klasę CSS active.
public class CustomNavLink : NavLink
{
protected override bool ShouldMatch(string currentUriAbsolute)
{
// Custom matching logic
}
}
Istnieją dwie NavLinkMatch opcje, które można przypisać do Match atrybutu <NavLink> elementu:
- NavLinkMatch.All: NavLink jest aktywna, gdy pasuje do całego bieżącego adresu URL, w tym ciągu zapytania i fragmentu.
- NavLinkMatch.Prefix (ustawienie domyślne): NavLink jest aktywny, gdy pasuje do dowolnego prefiksu bieżącego adresu URL.
Dodatkowe atrybuty składnika NavLink są przekazywane do renderowanego elementu zakotwiczenia. W poniższym przykładzie komponent NavLink zawiera atrybut target:
<NavLink href="example-page" target="_blank">Example page</NavLink>
Renderowane są następujące znaczniki HTML:
<a href="example-page" target="_blank">Example page</a>
Ostrzeżenie
Ze względu na sposób renderowania zawartości podrzędnej przez Blazor, składniki NavLink renderowane wewnątrz pętli for wymagają lokalnej zmiennej indeksu, jeśli zmienna iteracyjna pętli jest używana w zawartości składnika (podrzędnego) NavLink.
@for (int c = 1; c < 4; c++)
{
var ct = c;
<li ...>
<NavLink ...>
<span ...></span> Product #@ct
</NavLink>
</li>
}
Użycie zmiennej indeksu w tym scenariuszu jest wymaganiem dla
Alternatywnie użyj pętli z foreachEnumerable.Range:
@foreach (var c in Enumerable.Range(1, 3))
{
<li ...>
<NavLink ...>
<span ...></span> Product #@c
</NavLink>
</li>
}
Narzędzia do obsługi identyfikatorów URI i stanów nawigacji
Użyj NavigationManager do zarządzania identyfikatorami URI i nawigacją w kodzie C#. NavigationManager Zawiera zdarzenia i metody pokazane w poniższej tabeli.
| Członek | Description |
|---|---|
| Uri | Pobiera aktualny bezwzględny URI. |
| BaseUri | Pobiera podstawowy identyfikator URI (z końcowym ukośnikiem), który można poprzedzić względnymi ścieżkami identyfikatora URI w celu utworzenia bezwzględnego identyfikatora URI.
BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości). |
| NavigateTo | Przechodzi do określonego adresu URI. Jeśli forceLoad ma wartość false:
forceLoad ma wartość true:
Aby uzyskać więcej informacji, zobacz sekcję Rozszerzona nawigacja i obsługa formularzy . Jeśli |
| LocationChanged | Zdarzenie, które uruchamia się automatycznie po zmianie lokalizacji nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji . |
NotFound |
Wywoływana w celu obsługi scenariuszy, w których nie można odnaleźć żądanego zasobu. Aby uzyskać więcej informacji, zobacz sekcję Nie znaleziono odpowiedzi . |
| ToAbsoluteUri | Konwertuje względny identyfikator URI na bezwzględny identyfikator URI. |
| ToBaseRelativePath | Na podstawie identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na taki, który jest względny względem prefiksu podstawowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względnie do prefiksu podstawowego URI. |
RegisterLocationChangingHandler |
Rejestruje obsługę do przetwarzania przychodzących zdarzeń nawigacyjnych. Wywołanie NavigateTo zawsze uruchamia procedurę obsługi. |
| GetUriWithQueryParameter | Zwraca identyfikator URI utworzony przez aktualizację NavigationManager.Uri za pomocą pojedynczego parametru dodanego, zaktualizowanego lub usuniętego. Aby uzyskać więcej informacji, zobacz sekcję Ciągi zapytania. |
| Członek | Description |
|---|---|
| Uri | Pobiera aktualny bezwzględny URI. |
| BaseUri | Pobiera podstawowy identyfikator URI (z końcowym ukośnikiem), który można poprzedzić względnymi ścieżkami identyfikatora URI w celu utworzenia bezwzględnego identyfikatora URI.
BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości). |
| NavigateTo | Przechodzi do określonego adresu URI. Jeśli forceLoad ma wartość false:
forceLoad ma wartość true:
Aby uzyskać więcej informacji, zobacz sekcję Rozszerzona nawigacja i obsługa formularzy . Jeśli |
| LocationChanged | Zdarzenie, które uruchamia się automatycznie po zmianie lokalizacji nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji . |
| ToAbsoluteUri | Konwertuje względny identyfikator URI na bezwzględny identyfikator URI. |
| ToBaseRelativePath | Na podstawie identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na taki, który jest względny względem prefiksu podstawowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względnie do prefiksu podstawowego URI. |
RegisterLocationChangingHandler |
Rejestruje obsługę do przetwarzania przychodzących zdarzeń nawigacyjnych. Wywołanie NavigateTo zawsze uruchamia procedurę obsługi. |
| GetUriWithQueryParameter | Zwraca identyfikator URI utworzony przez aktualizację NavigationManager.Uri za pomocą pojedynczego parametru dodanego, zaktualizowanego lub usuniętego. Aby uzyskać więcej informacji, zobacz sekcję Ciągi zapytania. |
| Członek | Description |
|---|---|
| Uri | Pobiera aktualny bezwzględny URI. |
| BaseUri | Pobiera podstawowy identyfikator URI (z końcowym ukośnikiem), który można poprzedzić względnymi ścieżkami identyfikatora URI w celu utworzenia bezwzględnego identyfikatora URI.
BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości). |
| NavigateTo | Przechodzi do określonego adresu URI. Jeśli forceLoad ma wartość true:
replace jest true, bieżący identyfikator URI w historii przeglądarki zostanie zastąpiony, zamiast dodawać nowy identyfikator URI do stosu historii. |
| LocationChanged | Zdarzenie, które uruchamia się automatycznie po zmianie lokalizacji nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji . |
| ToAbsoluteUri | Konwertuje względny identyfikator URI na bezwzględny identyfikator URI. |
| ToBaseRelativePath | Na podstawie identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na taki, który jest względny względem prefiksu podstawowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względnie do prefiksu podstawowego URI. |
RegisterLocationChangingHandler |
Rejestruje obsługę do przetwarzania przychodzących zdarzeń nawigacyjnych. Wywołanie NavigateTo zawsze uruchamia procedurę obsługi. |
| GetUriWithQueryParameter | Zwraca identyfikator URI utworzony przez aktualizację NavigationManager.Uri za pomocą pojedynczego parametru dodanego, zaktualizowanego lub usuniętego. Aby uzyskać więcej informacji, zobacz sekcję Ciągi zapytania. |
| Członek | Description |
|---|---|
| Uri | Pobiera aktualny bezwzględny URI. |
| BaseUri | Pobiera podstawowy identyfikator URI (z końcowym ukośnikiem), który można poprzedzić względnymi ścieżkami identyfikatora URI w celu utworzenia bezwzględnego identyfikatora URI.
BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości). |
| NavigateTo | Przechodzi do określonego adresu URI. Jeśli forceLoad ma wartość true:
replace jest true, bieżący identyfikator URI w historii przeglądarki zostanie zastąpiony, zamiast dodawać nowy identyfikator URI do stosu historii. |
| LocationChanged | Zdarzenie, które uruchamia się automatycznie po zmianie lokalizacji nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji . |
| ToAbsoluteUri | Konwertuje względny identyfikator URI na bezwzględny identyfikator URI. |
| ToBaseRelativePath | Na podstawie identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na taki, który jest względny względem prefiksu podstawowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względnie do prefiksu podstawowego URI. |
| GetUriWithQueryParameter | Zwraca identyfikator URI utworzony przez aktualizację NavigationManager.Uri za pomocą pojedynczego parametru dodanego, zaktualizowanego lub usuniętego. Aby uzyskać więcej informacji, zobacz sekcję Ciągi zapytania. |
| Członek | Description |
|---|---|
| Uri | Pobiera aktualny bezwzględny URI. |
| BaseUri | Pobiera podstawowy identyfikator URI (z końcowym ukośnikiem), który można poprzedzić względnymi ścieżkami identyfikatora URI w celu utworzenia bezwzględnego identyfikatora URI.
BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości). |
| NavigateTo | Przechodzi do określonego adresu URI. Jeśli forceLoad ma wartość true:
|
| LocationChanged | Zdarzenie, które uruchamia się automatycznie po zmianie lokalizacji nawigacji. |
| ToAbsoluteUri | Konwertuje względny identyfikator URI na bezwzględny identyfikator URI. |
| ToBaseRelativePath | Na podstawie identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na taki, który jest względny względem prefiksu podstawowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względnie do prefiksu podstawowego URI. |
Zmiany lokalizacji
W odniesieniu do LocationChanged wydarzenia LocationChangedEventArgs przedstawia następujące informacje dotyczące zdarzeń nawigacji:
- Location: adres URL nowej lokalizacji.
-
IsNavigationIntercepted: Jeśli
true, Blazor przechwycił nawigację z przeglądarki. Jeślifalse, NavigationManager.NavigateTo spowodował, że nawigacja się odbyła.
Następujący składnik:
- Przechodzi do składnika aplikacji
Counter(Counter.razor) po wybraniu przycisku przy użyciu polecenia NavigateTo. - Obsługuje zdarzenie zmiany lokalizacji, poprzez subskrypcję NavigationManager.LocationChanged.
Metoda
HandleLocationChangedjest odpięta, gdyDisposejest wywoływana przez framework. Odłączanie metody umożliwia odzyskiwanie zasobów składnika.Implementacja rejestratora rejestruje następujące informacje po wybraniu przycisku:
BlazorSample.Pages.Navigate: Information: URL of new location: https://localhost:{PORT}/counter
Navigate.razor:
@page "/navigate"
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation
<h1>Navigate Example</h1>
<button class="btn btn-primary" @onclick="NavigateToCounterComponent">
Navigate to the Counter component
</button>
@code {
private void NavigateToCounterComponent() => Navigation.NavigateTo("counter");
protected override void OnInitialized() =>
Navigation.LocationChanged += HandleLocationChanged;
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) =>
Logger.LogInformation("URL of new location: {Location}", e.Location);
public void Dispose() => Navigation.LocationChanged -= HandleLocationChanged;
}
Aby uzyskać więcej informacji na temat usuwania komponentów, zobacz ASP.NET Core Razor komponentów.
Zachowanie przekierowania programu Navigation Manager podczas renderowania po stronie serwera statycznego (statyczny przewodnik SSR)
W przypadku przekierowania podczas renderowania statycznego po stronie serwera (statyczny przewodnik SSR) NavigationManager polega na zgłaszaniu NavigationException przechwyconego przez platformę elementu , który konwertuje błąd na przekierowanie. Kod, który istnieje po wywołaniu NavigateTo metody , nie jest wywoływany. W przypadku korzystania z programu Visual Studio debuger przerywa działanie wyjątku, co wymaga usunięcia zaznaczenia pola wyboru Przerwanie, gdy ten typ wyjątku jest obsługiwany przez użytkownika w interfejsie użytkownika programu Visual Studio, aby uniknąć zatrzymania debugera dla przyszłych przekierowań.
Możesz użyć <BlazorDisableThrowNavigationException> właściwości MSBuild ustawionej na true wartość w pliku projektu aplikacji, aby wyrazić zgodę, aby nie zgłaszać NavigationExceptionobiektu . Ponadto kod po wywołaniu do NavigateTo wykonania, gdy nie zostałby uruchomiony wcześniej. To zachowanie jest domyślnie włączone w szablonie projektu .NET 10 lub nowszym Blazor Web App :
<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>
Uwaga / Notatka
W programie .NET 10 lub nowszym możesz wyrazić zgodę, aby nie zgłaszać obiektu NavigationException , ustawiając <BlazorDisableThrowNavigationException> właściwość MSBuild na true wartość w pliku projektu aplikacji. Aby skorzystać z nowej właściwości i zachowania programu MSBuild, uaktualnij aplikację do platformy .NET 10 lub nowszej.
Nie znaleziono odpowiedzi
NavigationManager Udostępnia metodę NotFound obsługi scenariuszy, w których żądany zasób nie jest znaleziony podczas renderowania statycznego po stronie serwera (statycznego renderowania SSR) lub globalnego interaktywnego renderowania:
Statyczny SSR: wywołanie
NavigationManager.NotFoundustawia kod stanu HTTP na wartość 404.Renderowanie interakcyjne: sygnalizuje, że Blazor router (
Routerskładnik) renderuje zawartość Nie znaleziono.Renderowanie strumieniowe: jeśli rozszerzona nawigacja jest aktywna, renderowanie strumieniowe wyświetla zawartość oznaczoną jako "nie znaleziono" bez ponownego ładowania strony. Po zablokowaniu rozszerzonej nawigacji framework przekierowuje do zawartości "Not Found" poprzez odświeżenie strony.
Uwaga / Notatka
W poniższej dyskusji wspomniano, że komponent Nie znaleziono Razor można przypisać do parametru Router komponentu NotFoundPage. Parametr działa zgodnie z opisem NavigationManager.NotFound i został opisany bardziej szczegółowo w dalszej części tej sekcji.
Renderowanie strumieniowe może renderować tylko składniki, które mają trasę, takie jak NotFoundPage przypisanie (NotFoundPage="...") lub ponowne przypisanie strony kodu stanu (UseStatusCodePagesWithReExecute).
DefaultNotFound Zawartość 404 ("Not found" zwykły tekst) nie ma trasy, więc nie można jej używać podczas renderowania strumieniowego.
Uwaga / Notatka
Nie znaleziono fragmentu renderowania (<NotFound>...</NotFound>) nie jest obsługiwany w programie .NET 10 lub nowszym.
NavigationManager.NotFound renderowanie zawartości używa następujących elementów, niezależnie od tego, czy odpowiedź została uruchomiona, czy nie (w kolejności):
- Jeśli NotFoundEventArgs.Path jest ustawiona, renderuj zawartość przypisanej strony.
- Jeśli
Router.NotFoundPagejest ustawiona, renderuj przypisaną stronę. - Strona ponownego uruchamiania oprogramowania pośredniczącego z kodami statusu, jeśli została skonfigurowana.
- Brak działań, jeśli żadne z powyższych podejść nie zostanie przyjęte.
Oprogramowanie pośredniczące do ponownego wykonywania stron kodu stanu ma pierwszeństwo w przypadku problemów z routingu w przeglądarce, takich jak niepoprawny adres URL wpisany w pasku adresu przeglądarki lub wybranie linku bez punktu końcowego w aplikacji.
Gdy składnik jest renderowany statycznie (statyczny SSR) i NavigationManager.NotFound jest wywoływany, kod stanu 404 jest ustawiany dla odpowiedzi.
@page "/render-not-found-ssr"
@inject NavigationManager Navigation
@code {
protected override void OnInitialized()
{
Navigation.NotFound();
}
}
Aby udostępnić zawartość Not Found na potrzeby globalnego renderowania interaktywnego, użyj strony Not Found (Razor komponent).
Uwaga / Notatka
Szablon Blazor projektu zawiera NotFound.razor stronę. Ta strona jest automatycznie generowana za każdym razem, gdy NavigationManager.NotFound jest wywoływana, co umożliwia obsługę brakujących tras przy użyciu spójnego doświadczenia użytkownika.
Pages/NotFound.razor:
@page "/not-found"
@layout MainLayout
<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>
Składnik NotFound jest przypisywany do parametru routera NotFoundPage .
NotFoundPage obsługuje routing, który może być wykorzystywany w oprogramowaniu pośredniczącym do ponownego wykonywania dla stron kodu stanu, obejmując również middleware niezależne od Blazor.
W poniższym przykładzie poprzedni NotFound składnik znajduje się w folderze aplikacji Pages i jest przekazywany do parametru NotFoundPage.
<Router AppAssembly="@typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
<Found Context="routeData">
<RouteView RouteData="@routeData" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
Gdy składnik jest renderowany w globalnym trybie renderowania interaktywnego, wywołanie NavigationManager.NotFound sygnalizuje Blazor routerowi, aby renderował składnik NotFound.
@page "/render-not-found-interactive"
@inject NavigationManager Navigation
@if (RendererInfo.IsInteractive)
{
<button @onclick="TriggerNotFound">Trigger Not Found</button>
}
@code {
private void TriggerNotFound()
{
Navigation.NotFound();
}
}
Możesz użyć zdarzenia OnNotFound do powiadomień, gdy wywoływane jest NavigationManager.NotFound. Zdarzenie jest wyzwalane tylko wtedy, gdy NavigationManager.NotFound jest wywoływane, a nie dla żadnej odpowiedzi 404. Na przykład ustawienie HttpContextAccessor.HttpContext.Response.StatusCode na 404 nie powoduje wyzwolenia NavigationManager.NotFound/OnNotFound polecenia.
Aplikacje, które implementują router niestandardowy, mogą również używać polecenia NavigationManager.NotFound. Niestandardowy router może renderować zawartość „Nie znaleziono” z dwóch źródeł, w zależności od stanu odpowiedzi.
Niezależnie od stanu odpowiedzi, ścieżki ponownego wykonania do strony można użyć, przekazując ją do UseStatusCodePagesWithReExecute elementu:
app.UseStatusCodePagesWithReExecute( "/not-found", createScopeForStatusCodePages: true);Po rozpoczęciu odpowiedzi, NotFoundEventArgs.Path można użyć, subskrybując do
OnNotFoundEventw routerze.@code { [CascadingParameter] public HttpContext? HttpContext { get; set; } private void OnNotFoundEvent(object sender, NotFoundEventArgs e) { // Only execute the logic if HTTP response has started, // because setting NotFoundEventArgs.Path blocks re-execution if (HttpContext?.Response.HasStarted == false) { return; } var type = typeof(CustomNotFoundPage); var routeAttributes = type.GetCustomAttributes<RouteAttribute>(inherit: true); if (routeAttributes.Length == 0) { throw new InvalidOperationException($"The type {type.FullName} " + $"doesn't have a {nameof(RouteAttribute)} applied."); } var routeAttribute = (RouteAttribute)routeAttributes[0]; if (routeAttribute.Template != null) { e.Path = routeAttribute.Template; } } }
W poniższym przykładzie dla składników, które przyjmują interakcyjne renderowanie po stronie serwera (interakcyjne SSR), zawartość niestandardowa jest renderowana w zależności od tego, gdzie OnNotFound jest wywoływana. Jeśli zdarzenie zostanie wyzwolone przez następujący Movie składnik, gdy film nie zostanie znaleziony podczas inicjowania składnika, zostanie wyświetlony niestandardowy komunikat informujący o tym, że żądany film nie zostanie znaleziony. Jeśli zdarzenie zostanie wyzwolone przez User składnik w poniższym przykładzie, pojawi się inny komunikat, który informuje, że użytkownik nie został znaleziony.
Poniższa NotFoundContext usługa zarządza kontekstem i komunikatem, gdy zawartość nie zostanie znaleziona przez składniki.
NotFoundContext.cs:
public class NotFoundContext
{
public string? Heading { get; private set; }
public string? Message { get; private set; }
public void UpdateContext(string heading, string message)
{
Heading = heading;
Message = message;
}
}
Usługa jest zarejestrowana w pliku po stronie Program serwera:
builder.Services.AddScoped<NotFoundContext>();
Strona NotFound wstawia NotFoundContext i wyświetla nagłówek oraz komunikat.
Pages/NotFound.razor:
@page "/not-found"
@layout MainLayout
@inject NotFoundContext NotFoundContext
<h3>@NotFoundContext.Heading</h3>
<div>
<p>@NotFoundContext.Message</p>
</div>
Składnik Routes (Routes.razor) ustawia składnik NotFound jako stronę Nie znaleziono za pomocą parametru NotFoundPage.
<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
...
</Router>
Na przykładzie następujących komponentów:
- Usługa
NotFoundContextjest wstrzykiwana wraz z elementem NavigationManager. - W OnInitializedAsync,
HandleNotFoundjest obsługujący zdarzenie przypisany do zdarzeniaOnNotFound.HandleNotFoundwywołujeNotFoundContext.UpdateContextaby ustawić nagłówek i komunikat dla kontentu nie znaleziono w komponencieNotFound. - Komponenty zazwyczaj używają identyfikatora z parametru ścieżki, aby uzyskać film lub użytkownika z repozytorium danych, takiego jak baza danych. W poniższych przykładach żadna jednostka nie jest zwracana (
null), aby zasymulować, co się stanie, gdy jednostka nie zostanie znaleziona. - Gdy żaden element nie jest zwracany do OnInitializedAsync,
NavigationManager.NotFoundjest wywoływana, co z kolei wyzwala zdarzenieOnNotFoundi obsługę zdarzeńHandleNotFound. Router wyświetla komunikat "Nie znaleziono". - Metoda
HandleNotFoundjest odłączana przy usuwaniu komponentu w IDisposable.Dispose.
Movie komponent (Movie.razor):
@page "/movie/{Id:int}"
@implements IDisposable
@inject NavigationManager NavigationManager
@inject NotFoundContext NotFoundContext
<div>
No matter what ID is used, no matching movie is returned
from the call to GetMovie().
</div>
@code {
[Parameter]
public int Id { get; set; }
protected override async Task OnInitializedAsync()
{
NavigationManager.OnNotFound += HandleNotFound;
var movie = await GetMovie(Id);
if (movie == null)
{
NavigationManager.NotFound();
}
}
private void HandleNotFound(object? sender, NotFoundEventArgs e)
{
NotFoundContext.UpdateContext("Movie Not Found",
"Sorry! The requested movie wasn't found.");
}
private async Task<MovieItem[]?> GetMovie(int id)
{
// Simulate no movie with matching id found
return await Task.FromResult<MovieItem[]?>(null);
}
void IDisposable.Dispose()
{
NavigationManager.OnNotFound -= HandleNotFound;
}
public class MovieItem
{
public int Id { get; set; }
public string? Title { get; set; }
}
}
User komponent (User.razor):
@page "/user/{Id:int}"
@implements IDisposable
@inject NavigationManager NavigationManager
@inject NotFoundContext NotFoundContext
<div>
No matter what ID is used, no matching user is returned
from the call to GetUser().
</div>
@code {
[Parameter]
public int Id { get; set; }
protected override async Task OnInitializedAsync()
{
NavigationManager.OnNotFound += HandleNotFound;
var user = await GetUser(Id);
if (user == null)
{
NavigationManager.NotFound();
}
}
private void HandleNotFound(object? sender, NotFoundEventArgs e)
{
NotFoundContext.UpdateContext("User Not Found",
"Sorry! The requested user wasn't found.");
}
private async Task<UserItem[]?> GetUser(int id)
{
// Simulate no user with matching id found
return await Task.FromResult<UserItem[]?>(null);
}
void IDisposable.Dispose()
{
NavigationManager.OnNotFound -= HandleNotFound;
}
public class UserItem
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
Aby uzyskać dostęp do poprzednich składników w lokalnym pokazie za pomocą aplikacji testowej, utwórz wpisy w składniku NavMenu (NavMenu.razor), aby uzyskać dostęp do składników Movie i User. Identyfikatory jednostek, przekazane jako parametry trasy, w poniższym przykładzie są wartościami przykładowymi, które nie mają wpływu, ponieważ nie są faktycznie używane przez komponenty, które symulują nieznalezienie filmu ani użytkownika.
W pliku NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="movie/1">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Movie
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="user/2">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> User
</NavLink>
</div>
Ulepszona nawigacja i obsługa formularzy
Ta sekcja dotyczy Blazor Web Appów.
Blazor Web App są w stanie obsługiwać dwa typy routingu dla nawigacji stron i obsługi formularzy żądania:
- Normalna nawigacja (nawigacja między dokumentami): ponowne ładowanie pełnostronicowe jest wyzwalane dla adresu URL żądania.
- Ulepszona nawigacja (nawigacja w obrębie tego samego dokumentu): Blazor przechwytuje żądanie i zamiast tego wykonuje żądanie
fetch. Blazor następnie wprowadza poprawki do zawartości odpowiedzi w DOM strony. BlazorUlepszone funkcje nawigacji i obsługi formularzy eliminują konieczność pełnego przeładowania strony i pozwalają na lepsze zachowanie stanu strony, co sprawia, że strony ładują się szybciej, zwykle bez utraty położenia przewijania użytkownika.
Ulepszona nawigacja jest dostępna, gdy:
- Skrypt Blazor Web App (
blazor.web.js) jest używany, a nie Blazor Server skrypt (blazor.server.js) ani Blazor WebAssembly skrypt (blazor.webassembly.js). - Ta funkcja nie jest jawnie wyłączona.
- Docelowy adres URL znajduje się w wewnętrznej podstawowej przestrzeni identyfikatora URI (ścieżka podstawowa aplikacji), a link do strony nie ma ustawionego atrybutu
data-enhance-navna wartośćfalse.
Jeśli włączono routing po stronie serwera i rozszerzoną nawigację, programy obsługi zmieniające lokalizacje są wywoływane tylko w przypadku nawigacji programowej inicjowanej przez interakcyjne środowisko uruchomieniowe. W przyszłych wersjach dodatkowe typy nawigacji, takie jak przejście do linku, mogą również wywoływać procedury obsługujące zmiany lokalizacji.
W przypadku ulepszonej nawigacji LocationChanged obsługiwacze zdarzeń zarejestrowane w środowiskach uruchomieniowych Interactive Server i WebAssembly są zazwyczaj wywoływane. Istnieją przypadki, gdy programy obsługi zmiany lokalizacji mogą nie przechwytywać zaawansowanej nawigacji. Na przykład użytkownik może przełączyć się na inną stronę przed udostępnieniem interakcyjnego środowiska uruchomieniowego. Dlatego ważne jest, aby logika aplikacji nie polegała na wywoływaniu obsługi zmiany lokalizacji, ponieważ nie ma gwarancji jej wykonania.
Podczas wywoływania NavigateTo:
- Jeśli
forceLoadtofalse, co jest wartością domyślną:- Ulepszona nawigacja jest dostępna pod bieżącym adresem URL, Blazor i jest aktywowana.
- Blazor W przeciwnym razie wykonuje ponowne ładowanie pełnej strony dla żądanego adresu URL.
- Jeśli
forceLoadjesttrue: Blazor przeprowadza ponowne ładowanie całej strony dla żądanego adresu URL, niezależnie od tego, czy rozszerzona nawigacja jest dostępna.
Możesz odświeżyć bieżącą stronę, wywołując metodę NavigationManager.Refresh(bool forceLoad = false), która zawsze wykonuje rozszerzoną nawigację, jeśli jest dostępna. Jeśli rozszerzona nawigacja nie jest dostępna, Blazor wykonuje ponowne ładowanie pełnej strony.
Navigation.Refresh();
Przekaż true do parametru forceLoad , aby upewnić się, że ponowne ładowanie pełnostronicowe jest zawsze wykonywane, nawet jeśli jest dostępna rozszerzona nawigacja:
Navigation.Refresh(true);
Rozszerzona nawigacja jest domyślnie włączona, ale może być kontrolowana hierarchicznie i na podstawie linku przy użyciu atrybutu data-enhance-nav HTML.
Następujące przykłady wyłączają nawigację rozszerzoną:
<a href="redirect" data-enhance-nav="false">
GET without enhanced navigation
</a>
<ul data-enhance-nav="false">
<li>
<a href="redirect">GET without enhanced navigation</a>
</li>
<li>
<a href="redirect-2">GET without enhanced navigation</a>
</li>
</ul>
Jeśli miejsce docelowe nie jest punktem końcowym Blazor, ulepszona nawigacja nie ma zastosowania, a skrypt JavaScript po stronie klienta próbuje ponownie, ładując pełną stronę. To zapewnia brak wątpliwości dla frameworku w kwestii stron zewnętrznych, które nie powinny być łączone z istniejącą stroną.
Aby włączyć rozszerzoną obsługę formularzy, dodaj parametr Enhance do formularzy EditForm lub atrybut data-enhance do formularzy HTML (<form>):
<EditForm ... Enhance ...>
...
</EditForm>
<form ... data-enhance ...>
...
</form>
Ulepszona obsługa formularzy nie jest hierarchiczna i nie przepływa do formularzy podrzędnych:
Nieobsługiwane: nie można ustawić rozszerzonej nawigacji na elemencie przodka formularza, aby włączyć rozszerzoną nawigację dla formularza.
<div ... data-enhance ...>
<form ...>
<!-- NOT enhanced -->
</form>
</div>
Ulepszone posty formularza działają tylko z punktami końcowymi Blazor. Opublikowanie rozszerzonego formularza do punktu końcowego innego niż Blazor powoduje wystąpienie błędu.
Aby wyłączyć rozszerzoną nawigację:
- W przypadku elementu EditFormusuń Enhance parametr z elementu formularza (lub ustaw go na wartość
false:Enhance="false"). - W przypadku kodu HTML
<form>usuńdata-enhanceatrybut z elementu formularza (lub ustaw go na wartośćfalse:data-enhance="false").
BlazorUlepszona nawigacja i obsługa formularzy mogą cofnąć dynamiczne zmiany w modelu DOM, jeśli zaktualizowana zawartość nie jest częścią renderowaną na serwerze. Aby zachować zawartość elementu, użyj atrybutu data-permanent .
W poniższym przykładzie zawartość <div> elementu jest aktualizowana dynamicznie przez skrypt podczas ładowania strony:
<div data-permanent>
...
</div>
Gdy Blazor zostanie uruchomiony na kliencie, możesz użyć zdarzenia enhancedload do nasłuchiwania ulepszonych aktualizacji strony. Umożliwia to ponowne stosowanie zmian do modelu DOM, które mogły zostać cofnięte przez rozszerzoną aktualizację strony.
Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));
Aby wyłączyć rozszerzoną nawigację i obsługę formularzy globalnie, zobacz uruchamianie ASP.NET CoreBlazor.
Ulepszona nawigacja przy użyciu renderowania statycznego po stronie serwera (statyczna usługa SSR) wymaga szczególnej uwagi podczas ładowania kodu JavaScript. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript z renderowaniem statycznym po stronie serwera (static SSR) .
Utwórz URI względem prefiksu podstawowego URI
Na podstawie bazowego identyfikatora URI aplikacji, ToBaseRelativePath przekształca bezwzględny identyfikator URI na identyfikator URI względny do prefiksu bazowego identyfikatora URI.
Rozważmy następujący przykład:
try
{
baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
...
}
Jeśli podstawowy identyfikator URI aplikacji to https://localhost:8000, zostaną uzyskane następujące wyniki:
- Przekazanie
https://localhost:8000/segmentwinputURIskutkuje wbaseRelativePathsegment. - Przekazanie
https://localhost:8000/segment1/segment2winputURIskutkuje wbaseRelativePathsegment1/segment2.
Jeśli podstawowy identyfikator URI aplikacji nie jest zgodny z podstawowym identyfikatorem URI inputURI, zostanie zgłoszony ArgumentException.
Przekazywanie https://localhost:8001/segment w inputURI powoduje wystąpienie następującego wyjątku:
System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'
Stan historii nawigacji
Używa NavigationManager interfejsu API historii przeglądarki do utrzymania stanu historii nawigacji związanego z każdą zmianą lokalizacji dokonywaną przez aplikację. Utrzymywanie stanu historii jest szczególnie przydatne w scenariuszach przekierowania zewnętrznego, takich jak w przypadku uwierzytelniania użytkowników z zewnętrznymi dostawcami tożsamości. Aby uzyskać więcej informacji, zobacz sekcję Opcje nawigacji.
Opcje nawigacji
Przekaż NavigationOptions do NavigateTo w celu kontrolowania następujących zachowań:
-
ForceLoad: Pomiń routing po stronie klienta i wymuś przeglądarkę do załadowania nowej strony z serwera, bez względu na to, czy identyfikator URI jest obsługiwany przez router po stronie klienta. Domyślna wartość to
false. -
ReplaceHistoryEntry: Zastąp bieżący wpis w stosie historii. Jeśli
false, dodaj nowy wpis do stosu historii. Domyślna wartość tofalse. - HistoryEntryState: Pobiera lub ustawia stan, który ma być dołączany do wpisu historii.
Navigation.NavigateTo("/path", new NavigationOptions
{
HistoryEntryState = "Navigation state"
});
Aby uzyskać więcej informacji na temat uzyskiwania stanu skojarzonego z wpisem historii docelowej podczas obsługi zmian lokalizacji, zobacz sekcję Obsługa/zapobieganie zmianom lokalizacji.
Ciągi zapytań
Użyj atrybutu [SupplyParameterFromQuery] , aby określić, że parametr składnika pochodzi z ciągu zapytania.
Użyj atrybutu [SupplyParameterFromQuery] z atrybutem [Parameter], aby określić, że parametr komponentu składnika trasy pochodzi z ciągu zapytania.
Uwaga / Notatka
Parametry składnika mogą odbierać tylko wartości parametrów zapytania w routowalnych składnikach z dyrektywą @page.
Tylko routowalne składniki bezpośrednio odbierają parametry zapytania, aby uniknąć zakłócania przepływu informacji z góry na dół i aby kolejność przetwarzania parametrów była jasna, zarówno przez platformę, jak i przez aplikację. Ten projekt pozwala uniknąć drobnych usterek w kodzie aplikacji, które zostały napisane przy założeniu określonej kolejności przetwarzania parametrów. Możesz definiować niestandardowe parametry kaskadowe lub bezpośrednio przypisywać do zwykłych parametrów składnika w celu przekazania wartości parametrów zapytania do składników niezwiązanych z routingem.
Parametry składnika dostarczone z ciągu zapytania obsługują następujące typy:
-
bool,DateTime, ,decimal,doublefloatGuid,int,long, .string - Warianty dopuszczające wartość null poprzednich typów danych.
- Tablice powyższych typów, niezależnie od tego, czy mogą przyjmować wartość null, czy nie.
Poprawne formatowanie niezależne od kultury jest stosowane dla danego typu (CultureInfo.InvariantCulture).
Określ właściwość atrybutu [SupplyParameterFromQuery]Name , aby użyć nazwy parametru zapytania innej niż nazwa parametru składnika. W poniższym przykładzie nazwa języka C# parametru składnika to {COMPONENT PARAMETER NAME}. Dla symbolu zastępczego {QUERY PARAMETER NAME} określono inną nazwę parametru zapytania:
Właściwości [Parameter] można oznaczyć jako [SupplyParameterFromQuery] i jako private, w przeciwieństwie do właściwości parametru składnika (public).
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
private string? {COMPONENT PARAMETER NAME} { get; set; }
Podobnie jak właściwości parametrów składnika ([Parameter]), właściwości [SupplyParameterFromQuery] są zawsze właściwościami public w .NET 6/7. W programie .NET 8 lub nowszym właściwości [SupplyParameterFromQuery] można oznaczyć jako public lub private.
[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }
W poniższym przykładzie z adresem URL :/search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman
- Właściwość
Filterodnosi się doscifi stars. - Właściwość
Pageodnosi się do3. - Tablica
Starsjest wypełniana z parametrów zapytania o nazwiestar(Name = "star") i odwołuje się doLeVar BurtoniGary Oldman.
Uwaga / Notatka
Parametry ciągu zapytania w następującym komponencie strony routowalnej działają również w komponencie nieroutowalnym bez dyrektywy @page (na przykład Search.razor w przypadku współużytkowanego Search komponentu używanego w innych komponentach).
Search.razor:
@page "/search"
<h1>Search Example</h1>
<p>Filter: @Filter</p>
<p>Page: @Page</p>
@if (Stars is not null)
{
<p>Stars:</p>
<ul>
@foreach (var name in Stars)
{
<li>@name</li>
}
</ul>
}
@code {
[SupplyParameterFromQuery]
private string? Filter { get; set; }
[SupplyParameterFromQuery]
private int? Page { get; set; }
[SupplyParameterFromQuery(Name = "star")]
private string[]? Stars { get; set; }
}
Search.razor:
@page "/search"
<h1>Search Example</h1>
<p>Filter: @Filter</p>
<p>Page: @Page</p>
@if (Stars is not null)
{
<p>Stars:</p>
<ul>
@foreach (var name in Stars)
{
<li>@name</li>
}
</ul>
}
@code {
[Parameter]
[SupplyParameterFromQuery]
public string? Filter { get; set; }
[Parameter]
[SupplyParameterFromQuery]
public int? Page { get; set; }
[Parameter]
[SupplyParameterFromQuery(Name = "star")]
public string[]? Stars { get; set; }
}
Służy GetUriWithQueryParameter do dodawania, zmieniania lub usuwania co najmniej jednego parametru zapytania w bieżącym adresie URL:
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})
W poprzednim przykładzie:
- Symbol
{NAME}zastępczy określa nazwę parametru zapytania. Element{VALUE}zastępczy określa wartość jako obsługiwany typ. Obsługiwane typy są wymienione w dalszej części tej sekcji. - Zwracany jest ciąg równy bieżącemu adresowi URL z pojedynczym parametrem.
- Dodano, jeśli nazwa parametru zapytania nie istnieje w bieżącym adresie URL.
- Wartość została zaktualizowana na podaną, jeśli parametr zapytania istnieje w bieżącym adresie URL.
- Usunięto, jeśli typ podanej wartości ma wartość null, a wartość to
null.
- Poprawne formatowanie niezależne od kultury jest stosowane dla danego typu (CultureInfo.InvariantCulture).
- Nazwa i wartość parametru zapytania są zakodowane pod adresem URL.
- Wszystkie wartości o pasującej nazwie parametru zapytania są zastępowane, jeśli istnieje wiele wystąpień typu.
Wywołaj GetUriWithQueryParameters, aby utworzyć identyfikator URI skonstruowany z Uri z dodanymi, zaktualizowanymi lub usuniętymi wieloma parametrami. Dla każdej wartości, framework używa value?.GetType() do określenia typu w czasie uruchamiania dla każdego parametru zapytania i wybiera prawidłowe formatowanie niezależne od kultury. Struktura zgłasza błąd dla nieobsługiwanych typów.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters({PARAMETERS})
Zastępczy symbol {PARAMETERS} jest IReadOnlyDictionary<string, object>.
Aby GetUriWithQueryParameters wygenerować nowy identyfikator URI na podstawie podanego identyfikatora URI z dodatkowymi, zaktualizowanymi lub usuniętymi parametrami, przekaż ciąg identyfikatora URI. Dla każdej wartości, framework używa value?.GetType() do określenia typu w czasie uruchamiania dla każdego parametru zapytania i wybiera prawidłowe formatowanie niezależne od kultury. Struktura zgłasza błąd dla nieobsługiwanych typów. Obsługiwane typy są wymienione w dalszej części tej sekcji.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
- Symbol zastępczy
{URI}to identyfikator URI z ciągiem zapytania lub bez niego. - Zastępczy symbol
{PARAMETERS}jestIReadOnlyDictionary<string, object>.
Obsługiwane typy są identyczne z obsługiwanymi typami ograniczeń tras:
boolDateOnlyDateTimedecimaldoublefloatGuidintlongstringTimeOnly
Obsługiwane typy obejmują:
- Warianty dopuszczające wartość null poprzednich typów danych.
- Tablice powyższych typów, niezależnie od tego, czy mogą przyjmować wartość null, czy nie.
Ostrzeżenie
Dzięki kompresji, która jest domyślnie włączona, unikaj tworzenia bezpiecznych (uwierzytelnionych/autoryzowanych) interaktywnych składników po stronie serwera, które renderuje dane z niezaufanych źródeł. Niezaufane źródła obejmują parametry trasy, ciągi zapytań, dane z JS międzyoperacyjności i wszelkie inne źródło danych, które użytkownik zewnętrzny może kontrolować (bazy danych, usługi zewnętrzne). Aby uzyskać więcej informacji, zobacz wskazówki dotyczące ASP.NET CoreBlazorSignalR oraz wskazówki dotyczące łagodzenia zagrożeń dla interaktywnego renderowania po stronie serwera w ASP.NET CoreBlazor.
Zastąp wartość parametru zapytania, gdy parametr istnieje
Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
| Bieżący adres URL | Wygenerowany adres 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 |
Dołączanie parametru zapytania i wartości, gdy parametr nie istnieje
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
| Bieżący adres URL | Wygenerowany adres 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 |
Usuwanie parametru zapytania, gdy wartość parametru jest null
Navigation.GetUriWithQueryParameter("full name", (string)null)
| Bieżący adres URL | Wygenerowany adres 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/ |
Dodawanie, aktualizowanie i usuwanie parametrów zapytania
W poniższym przykładzie:
-
namezostanie usunięta, jeśli jest obecna. -
ageparametr jest dodawany z wartością25(int), jeśli nie istnieje. Jeśli jest obecny,agezostanie zaktualizowany do wartości25. -
eye colorjest dodawany lub aktualizowany do wartościgreen.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["name"] = null,
["age"] = (int?)25,
["eye color"] = "green"
})
| Bieżący adres URL | Wygenerowany adres 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 |
Obsługa wartości wyliczalnych
W poniższym przykładzie:
-
full namejest dodawany lub aktualizowany naMorena Baccarin, pojedynczą wartość. -
pingparametry są dodawane lub zastępowane parametrami35,1687i240.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["full name"] = "Morena Baccarin",
["ping"] = new int?[] { 35, 16, null, 87, 240 }
})
| Bieżący adres URL | Wygenerowany adres 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 |
Nawigowanie za pomocą dodanego lub zmodyfikowanego ciągu zapytania
Aby nawigować za pomocą dodanego lub zmodyfikowanego ciągu zapytania, przekaż wygenerowany adres URL do .NavigateTo
Następujące przykładowe wywołania:
-
GetUriWithQueryParameter aby dodać lub zamienić
nameparametr zapytania przy użyciu wartościMorena Baccarin. - Wywołanie NavigateTo powoduje nawigację do nowego adresu URL.
Navigation.NavigateTo(
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));
Ciąg zapytania w żądaniu jest uzyskiwany z właściwości NavigationManager.Uri.
@inject NavigationManager Navigation
...
var query = new Uri(Navigation.Uri).Query;
Aby przeanalizować parametry ciągu zapytania, jednym z podejść jest użycie interop z JavaScript (URLSearchParamsJS):
export createQueryString = (string queryString) => new URLSearchParams(queryString);
Aby uzyskać więcej informacji na temat izolacji języka JavaScript z modułami języka JavaScript, zobacz Wywoływanie funkcji Języka JavaScript z metod platformy .NET w programie ASP.NET Core Blazor.
Przejdź do nazwanych elementów
Przejdź do nazwanego elementu za pomocą następujących podejść z zahashowanym odwołaniem (#) do elementu. Trasy do elementów w składniku oraz trasy do elementów w składnikach zewnętrznych używają ścieżek względnych od katalogu głównego. Ukośnik początkowy (/) jest opcjonalny.
Przykłady każdego z poniższych podejść pokazują nawigację do elementu określonego przez idtargetElement w komponencie Counter.
Element kotwiczący (
<a>) zhref<a href="/counter#targetElement">NavLink komponent z elementem
href:<NavLink href="/counter#targetElement">NavigationManager.NavigateTo przekazywanie względnego adresu URL:
Navigation.NavigateTo("/counter#targetElement");
W poniższym przykładzie pokazano przechodzenie do nagłówków H2 w składniku i do składników zewnętrznych.
W składnikach Home (Home.razor) i Counter (Counter.razor) umieść następujące znaczniki u dołu istniejącego znacznika składnika, aby służyć jako elementy docelowe nawigacji. Funkcja <div> tworzy sztuczną przestrzeń pionową w celu zademonstrowania zachowania przewijania przeglądarki:
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
Dodaj następujący FragmentRouting składnik do aplikacji.
FragmentRouting.razor:
@page "/fragment-routing"
@inject NavigationManager Navigation
<PageTitle>Fragment routing</PageTitle>
<h1>Fragment routing to named elements</h1>
<ul>
<li>
<a href="/fragment-routing#targetElement">
Anchor in this component
</a>
</li>
<li>
<a href="/#targetElement">
Anchor to the <code>Home</code> component
</a>
</li>
<li>
<a href="/counter#targetElement">
Anchor to the <code>Counter</code> component
</a>
</li>
<li>
<NavLink href="/fragment-routing#targetElement">
Use a `NavLink` component in this component
</NavLink>
</li>
<li>
<button @onclick="NavigateToElement">
Navigate with <code>NavigationManager</code> to the
<code>Counter</code> component
</button>
</li>
</ul>
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
@code {
private void NavigateToElement()
{
Navigation.NavigateTo("/counter#targetElement");
}
}
Obsługa/zapobieganie zmianom lokalizacji
RegisterLocationChangingHandler rejestruje obsługiwacz w celu przetwarzania przychodzących zdarzeń nawigacyjnych. Kontekst obsługi udostępniany przez LocationChangingContext ma następujące właściwości:
- TargetLocation: Pobiera lokalizację docelową.
- HistoryEntryState: pobiera stan skojarzony z wpisem w historii celowej.
- IsNavigationIntercepted: Sprawdza, czy nawigacja została przechwycona z linku.
- CancellationToken: Pobiera CancellationToken, aby określić, czy nawigacja została anulowana, na przykład do ustalenia, czy użytkownik wywołał inną nawigację.
- PreventNavigation: wywoływana, aby uniemożliwić kontynuowanie nawigacji.
Składnik może zarejestrować wiele programów obsługi zmiany lokalizacji w metodzie cyklu życia OnAfterRender{Async}. Nawigacja wywołuje wszystkie programy obsługi zmieniające lokalizacje zarejestrowane w całej aplikacji (w wielu składnikach), a każda nawigacja wewnętrzna wykonuje je wszystkie równolegle. Oprócz NavigateTo wywoływane są również procedury obsługi:
- Podczas wybierania linków wewnętrznych, czyli linków wskazujących na adresy URL w ścieżce podstawowej aplikacji.
- Podczas nawigowania za pomocą przycisków do przodu i wstecz w przeglądarce.
Obsługiwacze są wykonywane tylko na potrzeby nawigacji wewnątrz aplikacji. Jeśli użytkownik wybierze link prowadzący do innej witryny lub ręcznie zmieni adres w pasku adresu na inny, obsługiwacze zmiany lokalizacji nie są wykonywane.
Zaimplementuj IDisposable i usuń zarejestrowane programy obsługi w celu ich wyrejestrowania. Aby uzyskać więcej informacji, zobacz usuwanie komponentów w ASP.NET Core Razor.
Ważne
Nie próbuj wykonywać zadań oczyszczania DOM za pośrednictwem interop języka JavaScript (JS) podczas obsługi zmian adresu.
MutationObserver Użyj wzorca w JS w kliencie. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
W poniższym przykładzie rejestruje się obsługę zmiany lokalizacji dla zdarzeń nawigacji.
NavHandler.razor:
@page "/nav-handler"
@implements IDisposable
@inject NavigationManager Navigation
<p>
<button @onclick="@(() => Navigation.NavigateTo("/"))">
Home (Allowed)
</button>
<button @onclick="@(() => Navigation.NavigateTo("/counter"))">
Counter (Prevented)
</button>
</p>
@code {
private IDisposable? registration;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
registration =
Navigation.RegisterLocationChangingHandler(OnLocationChanging);
}
}
private ValueTask OnLocationChanging(LocationChangingContext context)
{
if (context.TargetLocation == "/counter")
{
context.PreventNavigation();
}
return ValueTask.CompletedTask;
}
public void Dispose() => registration?.Dispose();
}
Ponieważ nawigacja wewnętrzna może zostać anulowana asynchronicznie, może wystąpić wiele nakładających się wywołań zarejestrowanych obsługiwaczy. Na przykład wiele wywołań programu obsługi może wystąpić, gdy użytkownik szybko wybierze przycisk Wstecz na stronie lub wybierze wiele linków przed wykonaniem nawigacji. Poniżej przedstawiono podsumowanie logiki nawigacji asynchronicznej:
- Jeśli zarejestrowano jakiekolwiek programy obsługi zmiany lokalizacji, nawigacja jest początkowo cofnięta do stanu początkowego, a następnie odtwarzana, jeśli nawigacja nie zostanie anulowana.
- W przypadku nakładania się żądań nawigacji najnowsze żądanie zawsze anuluje wcześniejsze żądania, co oznacza następujące kwestie:
- Aplikacja może traktować wiele opcji przycisków wstecz i do przodu jako pojedynczy wybór.
- Jeśli użytkownik wybierze wiele linków przed zakończeniem nawigacji, wybranie ostatniego linku określa nawigację.
Aby uzyskać więcej informacji na temat przekazywania NavigationOptions do NavigateTo w celu kontrolowania wpisów i stanu stosu historii nawigacji, zobacz sekcję Nawigacja opcje.
Aby uzyskać dodatkowy przykładowy kod, zobacz NavigationManagerComponent w BasicTestApp (źródło referencyjne dotnet/aspnetcore).
Uwaga / Notatka
Linki dokumentacyjne do źródła referencyjnego .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla obecne prace rozwojowe nad nadchodzącą wersją .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Składnik NavigationLock przechwytuje zdarzenia nawigacji, o ile jest renderowany, skutecznie "blokując" daną nawigację do momentu podjęcia decyzji o kontynuowaniu lub anulowaniu. Użyj NavigationLock gdy przechwytywanie nawigacji można ograniczyć do okresu istnienia składnika.
NavigationLock parametry:
-
ConfirmExternalNavigation Ustawia okno dialogowe przeglądarki, aby monitować użytkownika o potwierdzenie lub anulowanie nawigacji zewnętrznej. Domyślna wartość to
false. Wyświetlenie okna dialogowego potwierdzenia wymaga początkowej interakcji użytkownika ze stroną przed wyzwoleniem nawigacji zewnętrznej za pomocą adresu URL na pasku adresu przeglądarki. Aby uzyskać więcej informacji na temat wymagań dotyczących interakcji, zobacz Okno:beforeunloadzdarzenie. - OnBeforeInternalNavigation Ustawia wywołanie zwrotne dla zdarzeń nawigacji wewnętrznej.
W poniższym składniku NavLock:
- Próba przejścia do witryny internetowej firmy Microsoft musi zostać potwierdzona przez użytkownika, zanim nawigacja do
https://www.microsoft.comzakończy się pomyślnie. - PreventNavigation jest wywoływane, aby zapobiec nawigacji, jeśli użytkownik odmówi potwierdzenia jej za pośrednictwem wywołania międzyoperacyjnego języka JavaScript (JS), które uruchamia dialog .
NavLock.razor:
@page "/nav-lock"
@inject IJSRuntime JSRuntime
@inject NavigationManager Navigation
<NavigationLock ConfirmExternalNavigation="true"
OnBeforeInternalNavigation="OnBeforeInternalNavigation" />
<p>
<button @onclick="Navigate">Navigate</button>
</p>
<p>
<a href="https://www.microsoft.com">Microsoft homepage</a>
</p>
@code {
private void Navigate()
{
Navigation.NavigateTo("/");
}
private async Task OnBeforeInternalNavigation(LocationChangingContext context)
{
var isConfirmed = await JSRuntime.InvokeAsync<bool>("confirm",
"Are you sure you want to navigate to the root page?");
if (!isConfirmed)
{
context.PreventNavigation();
}
}
}
Aby uzyskać dodatkowy przykładowy kod, zobacz ConfigurableNavigationLock składnik w BasicTestApp (dotnet/aspnetcore źródle odwołania)..
Dynamicznie generowane NavLink komponenty przez refleksję
NavLink Wpisy komponentów można dynamicznie tworzyć z komponentów aplikacji za pomocą refleksji. W poniższym przykładzie przedstawiono ogólne podejście do dalszego dostosowywania.
W przypadku następującej demonstracji dla składników aplikacji jest używana spójna, standardowa konwencja nazewnictwa:
- Nazwy plików składników routable używają wielkich liter w stylu Pascal, na przykład
Pages/ProductDetail.razor. - Ścieżki plików składników routable pasują do ich adresów URL w stylu kebab-case‡, z myślnikami pojawiającymi się między słowami w szablonie trasy składnika. Na przykład składnik
ProductDetailz szablonem trasy/product-detail(@page "/product-detail") jest żądany w przeglądarce pod względnym adresem URL/product-detail.
†Pascal case (znany też jako upper camel case) to konwencja nazewnictwa bez spacji i interpunkcji, w której każdy wyraz, łącznie z pierwszym, zaczyna się wielką literą.
Kebab case to konwencja nazewnictwa bez spacji i znaków interpunkcyjnych, która używa małych liter i kresek między wyrazami.
W znaczniku Razor składnika NavMenu (NavMenu.razor) na domyślnej stronie Home, składniki NavLink są dodawane z kolekcji:
<div class="nav-scrollable"
onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="bi bi-house-door-fill-nav-menu"
aria-hidden="true"></span> Home
</NavLink>
</div>
+ @foreach (var name in GetRoutableComponents())
+ {
+ <div class="nav-item px-3">
+ <NavLink class="nav-link"
+ href="@Regex.Replace(name, @"(\B[A-Z]|\d+)", "-$1").ToLower()">
+ @Regex.Replace(name, @"(\B[A-Z]|\d+)", " $1")
+ </NavLink>
+ </div>
+ }
</nav>
</div>
Metoda GetRoutableComponents w @code bloku:
public IEnumerable<string> GetRoutableComponents() =>
Assembly.GetExecutingAssembly()
.ExportedTypes
.Where(t => t.IsSubclassOf(typeof(ComponentBase)))
.Where(c => c.GetCustomAttributes(inherit: true)
.OfType<RouteAttribute>()
.Any())
.Where(c => c.Name != "Home" && c.Name != "Error")
.OrderBy(o => o.Name)
.Select(c => c.Name);
Powyższy przykład nie zawiera następujących stron na renderowanej liście składników:
-
Homepage: Strona jest wyświetlana oddzielnie od automatycznie wygenerowanych linków, ponieważ powinna pojawić się na górze listy oraz ustawić parametrMatch. -
Errorpage: Do strony błędu przechodzi tylko system i nie powinna być wyświetlana.
Aby zademonstrować powyższy kod w przykładowej aplikacji, uzyskaj przykładowąBlazor Web App aplikację lub Blazor WebAssembly.