Udostępnij za pośrednictwem


ASP.NET Core Blazor routing i nawigacja

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu .NET 9.

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 bieżącą wersją, zobacz wersję tego artykułu dla .NET 9.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zobacz artykuł dotyczący .NET 9.

W tym artykule wyjaśniono, jak zarządzać Blazor routingiem żądań aplikacji i jak używać NavLink składnika do tworzenia linków nawigacyjnych.

Ważne

Przykłady kodu w tym artykule pokazują metody o nazwie , Navigationktóra jest wstrzykiwana NavigationManager w klasach i składnikach.

Routing statyczny i interakcyjny

Ta sekcja dotyczy Blazor Web Apps.

Jeśli włączono prerendering, Blazor router (Router komponent <Router> w systemie Routes.razor) wykonuje routing statyczny do komponentów podczas renderowania statycznego po stronie serwera (statyczne SSR). Ten typ routingu jest nazywany routingiem statycznym.

Po przypisaniu interakcyjnego trybu renderowania do składnika Routes, router Blazor staje się interaktywny po statycznym SSR ze statycznym routingiem na serwerze. Ten typ routingu jest nazywany routingiem interaktywnym.

Routery statyczne używają routingu punktu końcowego i ścieżki żądania HTTP w celu określenia, który składnik ma być renderowany. Gdy router staje się interaktywny, używa adresu URL dokumentu (adresu URL na pasku adresu przeglądarki), aby określić, który składnik ma być renderowany. Oznacza to, że router interaktywny może dynamicznie zmieniać składnik renderowany, jeśli adres URL dokumentu dynamicznie zmienia się na inny prawidłowy wewnętrzny adres URL i może to zrobić bez wykonywania żądania HTTP w celu pobrania nowej zawartości strony.

Routing interaktywny również uniemożliwia prerenderowanie, ponieważ nowa zawartość strony nie jest żądana z serwera w ramach normalnego żądania strony. Aby uzyskać więcej informacji, zobacz Prerenderowanie w ASP.NET CoreRazor komponentów.

Szablony tras

Komponent Router umożliwia routing do komponentów Razor i znajduje się w komponencie Routes aplikacji (Components/Routes.razor).

Składnik Router umożliwia routing do Razor komponentów. Składnik Router jest używany w składniku App (App.razor).

Gdy kompilowany jest składnik (.razor) z dyrektywą @page, wygenerowana klasa składnika jest dostarczana z RouteAttribute określającym szablon trasy składnika.

Po uruchomieniu aplikacji zestaw określony jako Router AppAssembly jest skanowany w celu zebrania informacji o trasach dla składników aplikacji, które mają element RouteAttribute.

W czasie wykonywania RouteView komponent:

Opcjonalnie określ parametr DefaultLayout z klasą układu dla składników, które nie określają układu za pomocą dyrektywy @layout. Szablony projektów platformyBlazorokreślają MainLayout składnik (MainLayout.razor) jako domyślny układ aplikacji. Aby uzyskać więcej informacji na temat układów, zobacz układy ASP.NET CoreBlazor.

Składniki obsługują wiele szablonów tras za pomocą wielu @page dyrektyw. Poniższy przykładowy składnik ładuje się na żądania dotyczące /blazor-route i /different-blazor-route.

BlazorRoute.razor:

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

<PageTitle>Routing</PageTitle>

<h1>Routing Example</h1>

<p>
    This page is reached at either <code>/blazor-route</code> or 
    <code>/different-blazor-route</code>.
</p>
@page "/blazor-route"
@page "/different-blazor-route"

<PageTitle>Routing</PageTitle>

<h1>Routing Example</h1>

<p>
    This page is reached at either <code>/blazor-route</code> or 
    <code>/different-blazor-route</code>.
</p>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>
@page "/blazor-route"
@page "/different-blazor-route"

<h1>Blazor routing</h1>

Ważne

Aby adresy URL były rozpoznawane poprawnie, aplikacja musi zawierać tag <base> (część <head> zawartości) ze ścieżką podstawową aplikacji określoną w atrybucie href. Aby uzyskać więcej informacji, zobacz Host and deploy ASP.NET Core Blazor.

Element Router nie wchodzi w interakcję z wartościami ciągu zapytania. Aby pracować z ciągami zapytania, zobacz sekcję Ciągi zapytania.

Alternatywą dla określenia szablonu trasy jako literału ciągu z dyrektywą @page jest użycie szablonów tras opartych na stałych z dyrektywą @attribute.

W poniższym przykładzie dyrektywa @page w składniku jest zastępowana dyrektywą @attribute oraz szablonem trasy opartym na stałej w elemencie Constants.CounterRoute, który jest ustawiany gdzie indziej w aplikacji na "/counter".

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

Uwaga

Od wydania wersji ASP.NET Core 5.0.1 i w przypadku wszelkich dodatkowych wydań 5.x składnik Router zawiera parametr PreferExactMatches ustawiony na wartość @true. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 3.1 do wersji 5.0.

Skupienie elementu na nawigacji

Składnik FocusOnNavigate ustawia fokus interfejsu użytkownika na element oparty na selektorze CSS po przejściu z jednej strony do innej.

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

Gdy składnik Router przejdzie do nowej strony, składnik FocusOnNavigate ustawia fokus na nagłówku najwyższego poziomu strony (<h1>). Jest to powszechna strategia zapewniania, że nawigacja po stronie jest ogłaszana podczas korzystania z czytnika zawartości ekranu.

Podaj zawartość niestandardową, gdy nie znaleziono zawartości

Składnik Router umożliwia aplikacji określanie zawartości niestandardowej, jeśli nie można odnaleźć zawartości dla żądanej trasy.

Ustaw zawartość niestandardową dla parametru RouterNotFound składnika:

<Router ...>
    ...
    <NotFound>
        ...
    </NotFound>
</Router>

Dowolne elementy mogą być używane jako zawartość parametru NotFound, na przykład inne komponenty interaktywne. Aby zastosować układ domyślny do NotFound zawartości, zobacz układy ASP.NET CoreBlazor.

Ważne

Blazor Web Appnie używają parametru NotFound (znaczników<NotFound>...</NotFound>), ale parametr jest obsługiwany† w celu zapewnienia zgodności z poprzednimi wersjami, aby uniknąć zmiany powodującej niezgodność w frameworku. Potok middleware ASP.NET Core działający na serwerze przetwarza żądania. Użyj technik po stronie serwera do obsługi nieprawidłowych żądań.

Obsługiwane w tym kontekście oznacza, że umieszczenie <NotFound>...</NotFound> znacznika nie powoduje wyjątku, ale jego użycie również nie jest skuteczne.

Aby uzyskać więcej informacji, w tym zalecane podejście do obsługi nieprawidłowych żądań, zobacz ASP.NET Core Blazor tryby renderowania.

Trasowanie do komponentów z wielu zestawów

Ta sekcja dotyczy Blazor Web Apps.

Użyj parametru Router składnika AdditionalAssemblies i konstruktora konwencji AddAdditionalAssemblies adresu końcowego, aby odnaleźć routowalne składniki w dodatkowych zestawach. W poniższych podsekcjach wyjaśniono, kiedy i jak używać każdego interfejsu API.

Routing statyczny

Aby odnaleźć składniki routowalne z dodatkowych zestawów na potrzeby statycznego renderowania po stronie serwera (statycznego SSR), nawet jeśli router później stanie się interaktywny dla renderowania interaktywnego, zestawy muszą zostać ujawnione w ramach Blazor. Wywołaj metodę AddAdditionalAssemblies z dodatkowymi zestawami dołączonymi do MapRazorComponents w pliku projektu Program serwera.

Poniższy przykład obejmuje routowalne komponenty w zestawieniu projektu BlazorSample.Client przy użyciu pliku projektu _Imports.razor.

app.MapRazorComponents<App>()
    .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);

Uwaga

Powyższe wskazówki dotyczą również scenariuszy biblioteki klas komponentów. Dodatkowe ważne wskazówki dotyczące bibliotek klas ASP.NET Core (RCLs) ze statycznym renderowaniem po stronie serwera (statycznym SSR) można znaleźć w .

Routing interaktywny

Interaktywny tryb renderowania można przypisać do Routes składnika (Routes.razor), co sprawia, że router Blazor staje się interaktywny po statycznym SSR i routingu na serwerze. Na przykład <Routes @rendermode="InteractiveServer" /> przypisuje interakcyjne renderowanie po stronie serwera (interakcyjne SSR) do składnika Routes. Składnik Router dziedziczy interaktywne renderowanie po stronie serwera (SSR) ze składnika Routes. Router staje się interaktywny po routingu statycznym na serwerze.

Nawigacja wewnętrzna na potrzeby routingu interakcyjnego nie obejmuje żądania nowej zawartości strony z serwera. W związku z tym wstępne renderowanie nie zachodzi w przypadku wewnętrznych żądań stron. Aby uzyskać więcej informacji, zobacz Prerenderowanie komponentów ASP.NET Core.

Jeśli składnik Routes jest zdefiniowany w projekcie serwera, parametr AdditionalAssemblies składnika Router powinien zawierać zestaw projektu .Client. Dzięki temu router działa prawidłowo podczas interaktywnego renderowania.

W poniższym przykładzie komponent Routes znajduje się w projekcie serwera, a plik _Imports.razor projektu BlazorSample.Client wskazuje zestaw do wyszukiwania routowalnych komponentów.

<Router
    AppAssembly="..."
    AdditionalAssemblies="[ typeof(BlazorSample.Client._Imports).Assembly ]">
    ...
</Router>

Dodatkowe zestawy są skanowane oprócz zestawu określonego w AppAssembly.

Uwaga

Powyższe wskazówki dotyczą również scenariuszy biblioteki klas komponentów.

Alternatywnie składniki routowalne istnieją tylko w projekcie .Client z globalnym interaktywnym lub automatycznym renderowaniem WebAssembly, a komponent Routes jest zdefiniowany w projekcie .Client, a nie w projekcie serwera. W takim przypadku nie ma zewnętrznych zestawów z routowalnymi składnikami, więc nie trzeba określać wartości dla AdditionalAssemblies elementu.

Ta sekcja dotyczy Blazor Server aplikacji.

Użyj parametru Router składnika AdditionalAssemblies i konstruktora konwencji punktów końcowych AddAdditionalAssemblies, aby odkrywać trasowalne składniki w dodatkowych zestawach.

W poniższym przykładzie Component1 jest składnikiem routingu zdefiniowanym w przywoływanej bibliotece klas składników o nazwie ComponentLibrary:

<Router
    AppAssembly="..."
    AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }">
    ...
</Router>

Dodatkowe zestawy są skanowane oprócz zestawu określonego w AppAssembly.

Parametry trasowania

Router używa parametrów tras, aby wypełnić odpowiednie parametry składnika o tej samej nazwie. Nazwy parametrów trasy są niewrażliwe na wielkość liter. W poniższym przykładzie text parametr przypisuje wartość segmentu trasy do właściwości składnika Text . Gdy zostanie złożone żądanie dla /route-parameter-1/amazing, zawartość jest renderowana jako Blazor is amazing!.

RouteParameter1.razor:

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

<PageTitle>Route Parameter 1</PageTitle>

<h1>Route Parameter Example 1</h1>

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

<PageTitle>Route Parameter 1</PageTitle>

<h1>Route Parameter Example 1</h1>

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

@code {
    [Parameter]
    public string Text { get; set; }
}
@page "/route-parameter-1/{text}"

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

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

Parametry opcjonalne są obsługiwane. W poniższym przykładzie parametr opcjonalny text przypisuje wartość segmentu trasy do właściwości Text składnika. Jeśli segment nie jest dostępny, wartość Text jest ustawiona na fantastic.

Parametry opcjonalne nie są obsługiwane. W poniższym przykładzie zastosowano dwie @page dyrektywy . Pierwsza dyrektywa zezwala na nawigację do składnika bez parametru. Druga dyrektywa przypisuje wartość parametru {text} trasy do właściwości składnika Text .

RouteParameter2.razor:

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

<PageTitle>Route Parameter 2</PageTitle>

<h1>Route Parameter Example 2</h1>

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

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

    protected override void OnParametersSet() => Text = Text ?? "fantastic";
}
@page "/route-parameter-2/{text?}"

<PageTitle>Route Parameter 2</PageTitle>

<h1>Route Parameter Example 2</h1>

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

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

    protected override void OnParametersSet() => Text = Text ?? "fantastic";
}
@page "/route-parameter-2/{text?}"

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

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

    protected override void OnParametersSet()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2/{text?}"

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

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

    protected override void OnParametersSet()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2/{text?}"

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

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

    protected override void OnParametersSet()
    {
        Text = Text ?? "fantastic";
    }
}
@page "/route-parameter-2"
@page "/route-parameter-2/{text}"

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

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

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

Kiedy używana jest metoda cyklu życia OnInitialized{Async} zamiast metody cyklu życia OnParametersSet{Async}, domyślne przypisanie właściwości Text do fantastic nie występuje, jeśli użytkownik nawigowanie odbywa się w obrębie tego samego składnika. Na przykład taka sytuacja pojawia się, gdy użytkownik przechodzi z adresu do /route-parameter-2/amazing/route-parameter-2. Gdy wystąpienie składnika trwa i akceptuje nowe parametry, metoda OnInitialized nie jest wywoływana ponownie.

Uwaga

Parametry trasy nie działają z wartościami ciągu zapytania. Aby pracować z ciągami zapytania, zobacz sekcję Ciągi zapytania.

Ograniczenia trasy

Ograniczenie trasy wymusza dopasowanie typu segmentu trasy do składnika.

W poniższym przykładzie trasa do komponentu User jest zgodna tylko jeśli:

  • Segment Id trasy znajduje się w adresie URL żądania.
  • Segment Id jest typem liczby całkowitej (int).

User.razor:

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

<PageTitle>User</PageTitle>

<h1>User Example</h1>

<p>User Id: @Id</p>

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

Uwaga

Ograniczenia trasy nie działają z wartościami ciągu zapytania. Aby pracować z ciągami zapytania, zobacz sekcję Ciągi zapytania.

Dostępne są ograniczenia tras przedstawione w poniższej tabeli. Aby zapoznać się z ograniczeniami tras zgodnymi z kulturą niezmienną, zobacz ostrzeżenie poniżej tabeli.

Ograniczenie Przykład Przykładowe dopasowania Niezmiennik
kultura
parowanie
bool {active:bool} true, FALSE Nie.
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Tak
decimal {price:decimal} 49.99, -1,000.01 Tak
double {weight:double} 1.234, -1,001.01e8 Tak
float {weight:float} 1.234, -1,001.01e8 Tak
guid {id:guid} 00001111-aaaa-2222-bbbb-3333cccc4444, {00001111-aaaa-2222-bbbb-3333cccc4444} Nie.
int {id:int} 123456789, -123456789 Tak
long {ticks:long} 123456789, -123456789 Tak
nonfile {parameter:nonfile} Nie BlazorSample.styles.css, nie favicon.ico Tak

Ostrzeżenie

Ograniczenia trasy, które weryfikują adres URL i są konwertowane na typ CLR (np. int lub DateTime) zawsze używają niezmiennej kultury. Te ograniczenia zakładają, że adres URL nie jest lokalizowalny.

Ograniczenia trasy działają również z parametrami opcjonalnymi. W poniższym przykładzie Id jest wymagany, ale Option jest opcjonalnym parametrem logicznym trasy.

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; }
}

Unikaj przechwytywania plików w parametrze trasy

Poniższy szablon trasy przypadkowo przechwytuje statyczne ścieżki zasobów w opcjonalnym parametrze trasy (Optional). Na przykład arkusz stylów aplikacji (.styles.css) jest przechwytywany, co powoduje podział stylów aplikacji:

@page "/{optional?}"

...

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

Aby ograniczyć parametr trasy do przechwytywania ścieżek innych niż pliki, użyj :nonfile ograniczenia w szablonie trasy:

@page "/{optional:nonfile?}"

Routing z adresami URL zawierającymi kropki

Domyślny szablon trasy po stronie serwera zakłada, że jeśli ostatni segment adresu URL żądania zawiera kropkę (.), to żądany jest plik. Na przykład względny adres URL /example/some.thing jest interpretowany przez router jako żądanie dla pliku o nazwie some.thing. Bez dodatkowej konfiguracji aplikacja zwraca odpowiedź 404 — Nie znaleziono , jeśli some.thing została przeznaczona do kierowania do składnika z dyrektywą @page i some.thing jest wartością parametru trasy. Aby użyć trasy z co najmniej jednym parametrem zawierającym kropkę, aplikacja musi skonfigurować trasę przy użyciu szablonu niestandardowego.

Rozważmy następujący Example składnik, który może odbierać parametr trasy z ostatniego segmentu adresu URL.

Example.razor:

@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}
@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string? Param { get; set; }
}
@page "/example/{param?}"

<p>
    Param: @Param
</p>

@code {
    [Parameter]
    public string Param { get; set; }
}
@page "/example"
@page "/example/{param}"

<p>
    Param: @Param
</p>

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

Aby zezwolić aplikacji hostowanego rozwiązania na kierowanie żądania z kropką w parametrze ścieżki, dodaj szablon zapasowej ścieżki pliku z opcjonalnym parametrem w pliku:

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

Aby skonfigurować aplikację Blazor Server do kierowania żądania z kropką w parametrze trasy param, dodaj szablon trasy awaryjnej z opcjonalnym parametrem w pliku Program.

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

Aby uzyskać więcej informacji, zobacz Routing na platformie ASP.NET Core.

Aby zezwolić Server aplikacji hostowanego Blazor WebAssemblyrozwiązania na kierowanie żądania kropką w parametrze param trasy, dodaj szablon trasy rezerwowego pliku z opcjonalnym parametrem w Startup.Configurepliku .

Startup.cs:

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

Aby skonfigurować aplikację Blazor Server do kierowania żądań, które zawierają kropkę w parametrze trasy param, dodaj szablon trasy stronę awaryjnej z opcjonalnym parametrem w Startup.Configure.

Startup.cs:

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

Aby uzyskać więcej informacji, zobacz Routing na platformie ASP.NET Core.

Parametry trasy ogólne

Parametry ogólne trasy, które przechwytują ścieżki w wielu granicach folderów, są obsługiwane w komponentach.

Parametry trasy catch-all (uniwersalne) to:

  • Nazwany, aby odpowiadać nazwie segmentu trasy. Nazewnictwo nie uwzględnia wielkości liter.
  • Typ string. Struktura nie zapewnia automatycznego rzutu.
  • Na końcu adresu URL.

CatchAll.razor:

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

<PageTitle>Catch All</PageTitle>

<h1>Catch All Parameters Example</h1>

<p>Add some URI segments to the route and request the page again.</p>

<p>
    PageRoute: @PageRoute
</p>

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

<PageTitle>Catch All</PageTitle>

<h1>Catch All Parameters Example</h1>

<p>Add some URI segments to the route and request the page again.</p>

<p>
    PageRoute: @PageRoute
</p>

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

@code {
    [Parameter]
    public string? PageRoute { get; set; }
}
@page "/catch-all/{*pageRoute}"

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

W przypadku adresu URL /catch-all/this/is/a/test z szablonem trasy /catch-all/{*pageRoute}, wartość PageRoute jest ustawiona na this/is/a/test.

Ukośniki i segmenty przechwyconej ścieżki są odkodowywane. W przypadku szablonu trasy /catch-all/{*pageRoute}, adres URL /catch-all/this/is/a%2Ftest%2A zwraca this/is/a/test*.

Pomocnicy identyfikatora URI i stanu 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 opis
Uri Pobiera bieżący bezwzględny identyfikator URI.
BaseUri Pobiera podstawowy identyfikator URI (z ukośnikiem końcowym), który można poprzedzać 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:
  • 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 forceLoad ma wartość true:
  • Routing po stronie klienta jest pomijany.
  • Przeglądarka jest zmuszona do załadowania nowej strony z serwera, niezależnie od tego, czy identyfikator URI jest zwykle obsługiwany przez router interaktywny po stronie klienta.

Aby uzyskać więcej informacji, zobacz sekcję Rozszerzona nawigacja i obsługa formularzy .

Jeśli 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 program obsługi w celu przetwarzania przychodzących zdarzeń nawigacji. Wywołanie NavigateTo zawsze wywołuje 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 opis
Uri Pobiera bieżący bezwzględny identyfikator URI.
BaseUri Pobiera podstawowy identyfikator URI (z ukośnikiem na końcu), który można dodać przed względnymi ścieżkami identyfikatora URI, aby utworzyć bezwzględny identyfikator URI. BaseUri Zazwyczaj odpowiada atrybutowi href elementu dokumentu <base> (lokalizacji <head> zawartości).
NavigateTo Przechodzi do określonego identyfikatora URI. Jeśli forceLoad ma wartość true:
  • Routing po stronie klienta jest pomijany.
  • Przeglądarka jest zmuszona do załadowania nowej strony z serwera, niezależnie od tego, czy identyfikator URI jest zwykle obsługiwany przez router po stronie klienta.
Jeśli replace jest true, bieżący identyfikator URI w historii przeglądarki zostanie zastąpiony, zamiast dodawać nowy identyfikator URI na stos historii.
LocationChanged Zdarzenie, które uruchamia się, gdy zmieniono lokalizację nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji .
ToAbsoluteUri Konwertuje względny identyfikator URI na bezwzględny identyfikator URI.
ToBaseRelativePath Na podstawie podstawowego identyfikatora URI aplikacji konwertuje bezwzględny URI na URI względny do prefiksu podstawowego URI. Aby zobaczyć przykład, zajrzyj do sekcji Tworzenie URI względem prefiksu bazowego URI.
RegisterLocationChangingHandler Rejestruje program obsługi w celu przetwarzania przychodzących zdarzeń nawigacji. Wywołanie NavigateTo zawsze uruchamia obsługę.
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 opis
Uri Pobiera bieżący bezwzględny identyfikator URI.
BaseUri Pobiera podstawowy identyfikator URI (z ukośnikiem końcowym), który można poprzedzać 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 identyfikatora URI. Jeśli forceLoad ma wartość true:
  • Routing po stronie klienta jest pomijany.
  • Przeglądarka jest zmuszona do załadowania nowej strony z serwera, niezależnie od tego, czy identyfikator URI jest zwykle obsługiwany przez router po stronie klienta.
Jeśli replace ma wartość true, bieżący identyfikator URI w historii przeglądarki zostanie zastąpiony zamiast dodania nowego identyfikatora URI do stosu historii.
LocationChanged Zdarzenie, które jest uruchamiane, gdy zmieni się lokalizacja nawigacji. Aby uzyskać więcej informacji, zobacz sekcję Zmiany lokalizacji .
ToAbsoluteUri Konwertuje względny identyfikator URI na bezwzględny identyfikator URI.
ToBaseRelativePath Na podstawie bazowego URI aplikacji, konwertuje bezwzględny URI na URI względny do prefiksu bazowego URI. Przykład można znaleźć w sekcji Tworzenie identyfikatora URI względem prefiksu podstawowego identyfikatora 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 opis
Uri Pobiera bieżący bezwzględny identyfikator URI.
BaseUri Pobiera podstawowy identyfikator URI (z ukośnikiem końcowym), który można poprzedzać 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 identyfikatora URI. Jeśli forceLoad ma wartość true:
  • Routing po stronie klienta jest pomijany.
  • Przeglądarka jest zmuszona do załadowania nowej strony z serwera, niezależnie od tego, czy identyfikator URI jest zwykle obsługiwany przez router po stronie klienta.
LocationChanged Zdarzenie, które uruchamia się, gdy zmienia się lokalizacja nawigacji.
ToAbsoluteUri Konwertuje względny identyfikator URI na bezwzględny identyfikator URI.
ToBaseRelativePath Na podstawie podstawowego identyfikatora URI aplikacji konwertuje bezwzględny identyfikator URI na identyfikator URI względem prefiksu podstawowego identyfikatora URI. Przykład można znaleźć w sekcji Generowanie identyfikatora URI względem podstawowego prefiksu URI.

Zmiany lokalizacji

W odniesieniu do LocationChanged wydarzenia LocationChangedEventArgs przedstawia następujące informacje dotyczące zdarzeń nawigacji:

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 HandleLocationChanged jest odpięta, gdy Dispose jest wywoływana przez framework. Odłączanie metody umożliwia odzyskiwanie pamięci 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

<PageTitle>Navigate</PageTitle>

<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;
}
@page "/navigate"
@implements IDisposable
@inject ILogger<Navigate> Logger
@inject NavigationManager Navigation

<PageTitle>Navigate</PageTitle>

<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;
}
@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;
    }
}
@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;
    }
}
@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;
    }
}
@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;
    }
}

Aby uzyskać więcej informacji na temat usuwania składników, zobacz cykl życia składników ASP.NET Core.

Ulepszona nawigacja i obsługa formularzy

Ta sekcja dotyczy Blazor Web Apps.

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 modelu 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 przestrzeni podstawowego identyfikatora URI (ścieżka podstawowa aplikacji).

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 forceLoad to false, co jest wartością domyślną:
    • Ulepszona nawigacja jest dostępna pod bieżącym adresem URL, Blazora ulepszona nawigacja jest aktywowana.
    • Blazor W przeciwnym razie wykonuje ponowne ładowanie pełnej strony dla żądanego adresu URL.
  • Jeśli forceLoad jest true: 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ę. Dzięki temu nie ma wątpliwości co do struktury stron zewnętrznych, które nie powinny być poprawiane na istniejącej stronie.

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>

Rozszerzone wpisy formularza działają tylko z punktami Blazor końcowymi. 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-enhance atrybut 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/segment w inputURI skutkuje w baseRelativePathsegment.
  • Przekazywanie https://localhost:8000/segment1/segment2 w inputURI prowadzi do baseRelativePathsegment1/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/'.'

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.

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ść to false.
  • 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

Parametry składnika mogą odbierać tylko wartości parametrów zapytania w składnikach routingu 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, double, float, Guid, 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 przeciwieństwie do właściwości parametru składnika ([Parameter]), [SupplyParameterFromQuery] właściwości można oznaczyć private oprócz 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ść Filter odnosi się do scifi stars.
  • Właściwość Page rozwiązuje się do 3.
  • Tablica Stars jest wypełniana z parametrów zapytania o nazwie star (Name = "star") i odwołuje się do LeVar Burton i Gary Oldman.

Uwaga

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.
  • Ciąg jest zwracany jako bieżący adres 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})

Symbol {PARAMETERS} zastępczy to 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 czasu działania 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.
  • Symbol {PARAMETERS} zastępczy to IReadOnlyDictionary<string, object>.

Obsługiwane typy są identyczne z obsługiwanymi typami ograniczeń tras:

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

Obsługiwane typy obejmują:

  • Odmiany dopuszczające wartość null dla poprzednich typów.
  • Tablice powyższych typów, niezależnie od tego, czy są dopuszczalne wartości 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 ścieżki, ciągi zapytań, dane z JS międzyoperacyjności i inne źródła danych, które użytkownik zewnętrzny może kontrolować (np. 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:

  • name zostanie usunięta, jeśli jest obecna.
  • age parametr jest dodawany z wartością 25 (int), jeśli nie istnieje. Jeśli jest obecny, age zostanie zaktualizowany do wartości 25.
  • eye color jest dodawany lub aktualizowany do wartości green.
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 name jest dodawany lub aktualizowany na Morena Baccarin, pojedynczą wartość.
  • pingparametry są dodawane lub zastępowane parametrami 35, 1687 i 240.
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

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ć name parametr zapytania przy użyciu wartości Morena Baccarin.
  • Wywołania NavigateTo wyzwalające 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.

Haszowany routing 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 wiodący (/) jest opcjonalny.

Przykłady dla każdego z poniższych podejść pokazują nawigację do elementu z elementem idtargetElement w składniku Counter :

  • Element kotwicy (<a>) z elementem href:

    <a href="/counter#targetElement">
    
  • NavLink składnik z elementem href:

    <NavLink href="/counter#targetElement">
    
  • NavigationManager.NavigateTo Przekazywanie względnego adresu URL:

    Navigation.NavigateTo("/counter#targetElement");
    

W poniższym przykładzie pokazano hashowany routing do nazwanych nagłówków H2 w komponencie oraz do zewnętrznych komponentów.

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 HashedRouting składnik do aplikacji.

HashedRouting.razor:

@page "/hashed-routing"
@inject NavigationManager Navigation

<PageTitle>Hashed routing</PageTitle>

<h1>Hashed routing to named elements</h1>

<ul>
    <li>
        <a href="/hashed-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="/hashed-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");
    }
}

Interakcja użytkownika z zawartością <Navigating>

Jeśli podczas nawigacji występuje znaczne opóźnienie, na przykład podczas ładowania zestawów z opóźnieniem w Blazor WebAssembly aplikacji lub w przypadku powolnego połączenia sieciowego z Blazor aplikacją po stronie serwera, Router składnik może wskazywać użytkownikowi, że następuje przejście strony.

Na górze składnika, który określa komponent Router, dodaj dyrektywę @using dla przestrzeni nazw Microsoft.AspNetCore.Components.Routing.

@using Microsoft.AspNetCore.Components.Routing

Podaj zawartość dla parametru Navigating do wyświetlenia podczas zdarzeń przejścia strony.

W elemecie routera (<Router>...</Router>) zawartość:

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

Aby zapoznać się z przykładem, który używa Navigating właściwości, zobacz Ładowanie zestawów z opóźnieniem w programie ASP.NET Core Blazor WebAssembly.

Obsługa zdarzeń nawigacji asynchronicznej za pomocą polecenia OnNavigateAsync

Składnik Router obsługuje OnNavigateAsync funkcję. Procedura obsługi OnNavigateAsync jest wywoływana, gdy użytkownik:

  • Odwiedza trasę po raz pierwszy, przechodząc do niej bezpośrednio w przeglądarce.
  • Przechodzi do nowej ścieżki przy użyciu linku lub wywołania NavigationManager.NavigateTo.
<Router AppAssembly="typeof(App).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

@code {
    private async Task OnNavigateAsync(NavigationContext args)
    {
        ...
    }
}
<Router AppAssembly="typeof(Program).Assembly" 
    OnNavigateAsync="OnNavigateAsync">
    ...
</Router>

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

Aby zapoznać się z przykładem, który używa OnNavigateAsync, zobacz Ładowanie z opóźnieniem zestawów w ASP.NET Core Blazor WebAssembly.

Podczas prerenderingu na serwerze OnNavigateAsync jest wykonywane dwa razy:

  • Raz, gdy żądany składnik punktu końcowego jest początkowo renderowany statycznie.
  • Po raz drugi, gdy przeglądarka renderuje składnik punktu końcowego.

Aby zapobiec dwukrotnemu wykonaniu kodu OnNavigateAsync dewelopera, Routes komponent może przechowywać NavigationContext zmienną do użycia w metodzie OnAfterRender{Async} cyklu życia, gdzie firstRender można to sprawdzić. Aby uzyskać więcej informacji, zobacz Wstępne renderowanie przy użyciu interakcji z językiem JavaScript.

Aby zapobiec dwukrotnemu wykonywaniu kodu dewelopera w OnNavigateAsync, komponent App może przechowywać NavigationContext do użycia w OnAfterRender{Async}, gdzie można sprawdzić firstRender. Aby uzyskać więcej informacji, zobacz Wstępne renderowanie z użyciem międzyoperacji języka JavaScript.

Obsługa anulowań w OnNavigateAsync

Obiekt NavigationContext przekazany do wywołania zwrotnego OnNavigateAsync zawiera element CancellationToken, który jest ustawiany, gdy wystąpi nowe zdarzenie nawigacji. Wywołanie OnNavigateAsync powinno zakończyć działanie, gdy ten token anulowania zostanie ustawiony, aby uniknąć kontynuowania uruchamiania OnNavigateAsync wywołania zwrotnego podczas nieaktualnej nawigacji.

Jeśli użytkownik przejdzie do punktu końcowego, ale natychmiast przejdzie do nowego punktu końcowego, aplikacja nie powinna kontynuować uruchamiania OnNavigateAsync wywołania zwrotnego dla pierwszego punktu końcowego.

W poniższym przykładzie:

  • Token anulowania jest przekazywany w wywołaniu PostAsJsonAsync, co może anulować żądanie POST, jeśli użytkownik przejdzie z dala od punktu końcowego /about.
  • Token anulowania jest ustawiany podczas operacji pobierania wstępnego produktu, jeśli użytkownik przechodzi z dala od punktu końcowego /store .
@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 = new[] { 345, 789, 135, 689 };

            foreach (var productId in productIds) 
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                Products.Prefetch(productId);
            }
        }
    }
}
@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 = new[] { 345, 789, 135, 689 };

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

Uwaga

Brak rzucania wyjątku, kiedy token anulowania w NavigationContext jest anulowany, może prowadzić do niezamierzonego zachowania, takiego jak renderowanie składnika z poprzedniej nawigacji.

Obsługa/zapobieganie zmianom lokalizacji

RegisterLocationChangingHandler rejestruje program obsługi w celu przetwarzania przychodzących zdarzeń nawigacji. Kontekst obsługi udostępniany przez LocationChangingContext ma następujące właściwości:

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 procedur obsługi są wywoływane:

  • 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 Cykl życia składników platformy ASP.NET Core Razor.

Ważne

Nie próbuj wykonywać zadań oczyszczania MODELU DOM za pośrednictwem międzyoperacji języka JavaScript (JS) podczas obsługi zmian lokalizacji. 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 program obsługi zmieniającej lokalizację jest rejestrowany 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

Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .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 platformy 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: beforeunload zdarzenie (dokumentacja MDN).
  • 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.com zakoń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 JSconfirm.

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)..

NavLink Podczas tworzenia linków nawigacyjnych użyj składnika zamiast elementów hiperłącza HTML (<a>). NavLink Składnik działa jak <a> element, z tą różnicą, że przełącza klasę active CSS w oparciu o zgodność jego href z bieżącym adresem 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.

Istnieją dwie NavLinkMatch opcje, które można przypisać do Match atrybutu <NavLink> elementu:

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 odwiedza dowolny adres URL z prefiksem component (na przykład /component i /component/another-segment).

Dodatkowe NavLink atrybuty składnika są przekazywane do renderowanego tagu kotwicy. 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 każdego składnika podrzędnego, który używa zmiennej pętli w swojej zawartości , a nie tylko składnika .

Alternatywnie użyj pętli z foreachEnumerable.Range:

@foreach (var c in Enumerable.Range(1, 3))
{
    <li ...>
        <NavLink ...>
            <span ...></span> Product #@c
        </NavLink>
    </li>
}

NavLink wpisy składników można dynamicznie tworzyć na podstawie składników aplikacji za pośrednictwem odbicia. 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 ProductDetail z szablonem trasy /product-detail (@page "/product-detail") jest żądany w przeglądarce pod względnym adresem URL /product-detail.

†Notacja Pascal to konwencja nazewnictwa, w której nie stosuje się spacji ani interpunkcji, a każdy wyraz zaczyna się wielką literą, w tym pierwszy wyraz.
{Przypadek Kebab to konwencja nazewnictwa bez spacji i znaków interpunkcyjnych, która używa małych liter i kreski 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:

  • Home page: Strona jest wyświetlana oddzielnie od automatycznie wygenerowanych linków, ponieważ powinna pojawić się na górze listy oraz ustawić parametr Match.
  • Error page: Do strony błędu przechodzi tylko system i nie powinna być wyświetlana.

Aby uzyskać przykładową aplikację zawierającą poprzedni kod, którą można uruchomić lokalnie, pobierz aplikację przykładową Blazor Web App lub Blazor WebAssembly.

integracja routingu punktów końcowych ASP.NET Core

Ta sekcja dotyczy Blazor Web Appdziałających nad obwodem.

Ta sekcja dotyczy Blazor Server aplikacji.

Element Blazor Web App jest zintegrowany z routingiem punktów końcowych w ASP.NET Core. Aplikacja ASP.NET Core jest skonfigurowana do akceptowania połączeń przychodzących dla składników MapRazorComponents interakcyjnych w Program pliku. Domyślny składnik główny (pierwszy załadowany składnik) to App składnik (App.razor):

app.MapRazorComponents<App>();

Blazor Server jest zintegrowany z routingiem punktów końcowych platformy ASP.NET Core. Aplikacja ASP.NET Core jest skonfigurowana do akceptowania połączeń przychodzących dla składników MapBlazorHub interaktywnych w Program pliku :

app.UseRouting();

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

Blazor Server jest zintegrowany z routingiem punktów końcowych platformy ASP.NET Core. Aplikacja ASP.NET Core jest skonfigurowana do akceptowania połączeń przychodzących do składników interaktywnych za pomocą MapBlazorHub w Startup.Configure.

Typowa konfiguracja polega na kierowaniu wszystkich żądań do Razor strony, która działa jako host dla części Blazor Server aplikacji po stronie serwera. Zgodnie z konwencją strona hosta jest zwykle nazwana _Host.cshtml w Pages folderze aplikacji.

Trasa określona w pliku hosta jest nazywana trasą zapasową, ponieważ działa z niskim priorytetem w dopasowywaniu tras. Trasa rezerwowa jest używana, gdy inne trasy nie są zgodne. Dzięki temu aplikacja może korzystać z innych kontrolerów i stron bez zakłócania routingu składników w ramach appki Blazor Server.

Aby uzyskać informacje na temat konfigurowania hostowania MapFallbackToPage serwera adresu URL innego niż główny, zobacz Host and deploy ASP.NET Core Blazor.