Sdílet prostřednictvím


Navigace ASP.NET Core Blazor

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

Výstraha

Tato verze ASP.NET Core již není podporována. Pro více informací se podívejte na Zásady podpory .NET a .NET Core. Aktuální verzi najdete ve verzi .NET 10 tohoto článku.

Tento článek vysvětluje, jak aktivovat a zpracovat navigaci na stránce v Blazor. I když uživatelé můžou přecházet mezi různými stránkami pomocí normálních odkazů HTML, vylepšuje navigaci v aplikaci, Blazor aby se zabránilo opětovnému načítání celé stránky a poskytovalo plynulejší prostředí. NavLink Pomocí komponenty můžete vytvořit navigační odkazy, které automaticky použijí styl, když odkaz odpovídá aktuální stránce. Pro programovou navigaci a správu identifikátorů URI v kódu jazyka NavigationManager C# použijte službu.

Tento článek vysvětluje, jak aktivovat a zpracovat navigaci na stránce v Blazor. NavLink Pomocí komponenty můžete vytvořit navigační odkazy, které automaticky použijí styl, když odkaz odpovídá aktuální stránce. Pro programovou navigaci a správu identifikátorů URI v kódu jazyka NavigationManager C# použijte službu.

Důležité

Příklady kódu v tomto článku ukazují metody volané na Navigation, což je injektované NavigationManager do tříd a komponent.

NavLink Při vytváření navigačních odkazů použijte součást místo elementů hypertextového odkazu HTML (<a>). Komponenta NavLink se chová jako <a> prvek, s výjimkou toho, že přepíná active třídu CSS na základě toho, jestli odpovídá href aktuální adrese URL. Třída active pomáhá uživateli pochopit, která stránka je aktivní stránkou mezi zobrazenými navigačními odkazy. Volitelně můžete přiřadit název třídy CSS k NavLink.ActiveClass, abyste použili vlastní třídu CSS na vykreslený odkaz, pokud aktuální trasa odpovídá href.

V komponentě NavMenu (NavMenu.razor) aplikace Blazor vytvořené pomocí projektové šablony 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>

V předchozím příkladu HomeNavLinkhref="" odpovídá domovské adrese URL a obdrží pouze třídu active CSS ve výchozí základní cestě aplikace (/). NavLink Druhý prvek obdrží třídu active ve chvíli, kdy uživatel navštíví komponentu Counter na adrese /counter.

K atributu NavLinkMatch elementu Match můžete přiřadit dvě <NavLink> možnosti:

  • NavLinkMatch.All: NavLink je aktivní, pokud odpovídá aktuální adrese URL, ignoruje řetězec dotazu a fragment. Pokud chcete do řetězce dotazu nebo fragmentu zahrnout shodu, použijte Microsoft.AspNetCore.Components.Routing.NavLink.EnableMatchAllForQueryStringAndFragmentAppContext přepínač nastavený na true.
  • NavLinkMatch.Prefix (výchozí): Je NavLink aktivní, pokud odpovídá jakékoli předponě aktuální adresy URL.

Chcete-li použít vlastní logiku porovnávání, vytvořte podtřídu z NavLink a přepište její metodu ShouldMatch. Vraťte true z metody, pokud chcete použít třídu active CSS.

public class CustomNavLink : NavLink
{
    protected override bool ShouldMatch(string currentUriAbsolute)
    {
        // Custom matching logic
    }
}

K atributu NavLinkMatch elementu Match můžete přiřadit dvě <NavLink> možnosti:

Další atributy komponenty NavLink jsou předávány do vykreslené kotvy. V následujícím příkladu komponenta NavLink obsahuje atribut target.

<NavLink href="example-page" target="_blank">Example page</NavLink>

Zobrazí se následující kód HTML:

<a href="example-page" target="_blank">Example page</a>

Výstraha

Vzhledem k tomu, jak Blazor vykresluje podřízený obsah, vykreslení komponent NavLink uvnitř cyklu for vyžaduje lokální indexovou proměnnou, pokud se proměnná inkrementace smyčky NavLink používá v obsahu podřízené komponenty.

@for (int c = 1; c < 4; c++)
{
    var ct = c;
    <li ...>
        <NavLink ...>
            <span ...></span> Product #@ct
        </NavLink>
    </li>
}

cs-CZ: Použití proměnné indexu v tomto scénáři je požadavek na libovolnou podřízenou komponentu, která používá proměnnou smyčky ve svém podřízeném obsahu, nejen komponentu NavLink.

Alternativně použijte smyčku foreach s Enumerable.Range:

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

Pomocníci pro URI a stav navigace

Použijte NavigationManager ke správě identifikátorů URI a navigace v kódu jazyka C#. NavigationManager poskytuje události a metody uvedené v následující tabulce.

Člen Description
Uri Získá aktuální absolutní identifikátor URI.
BaseUri Získá základní identifikátor URI (s koncovým lomítkem), který lze připojit na začátek relativních cest URI k vytvoření absolutního identifikátoru URI. Obvykle BaseUri odpovídá href atributu elementu dokumentu <base> (umístění <head> obsahu).
NavigateTo Přejde na zadané URI. Pokud forceLoad je false:
  • Vylepšená navigace je k dispozici na aktuální adrese URL, Blazorje aktivována vylepšená navigace.
  • Blazor V opačném případě se pro požadovanou adresu URL znovu načte celá stránka.
Pokud forceLoad je true:
  • Směrování na straně klienta se vynechá.
  • Prohlížeč je nucen načíst novou stránku ze serveru bez ohledu na to, jestli je identifikátor URI obvykle zpracován interaktivním směrovačem na straně klienta.

Další informace najdete v části Rozšířená navigace a zpracování formulářů.

Pokud replace je true, aktuální identifikátor URI v historii prohlížeče se nahradí místo přidání nového identifikátoru URI do zásobníku historie.

LocationChanged Událost, která se aktivuje po změně polohy navigace. Další informace najdete v části Změny polohy.
NotFound Volané pro zpracování scénářů, kdy nebyl nalezen požadovaný prostředek. Další informace najdete v části Odpovědi nenalezena .
ToAbsoluteUri Převede relativní identifikátor URI na absolutní identifikátor URI.
ToBaseRelativePath Na základě základního URI aplikace převádí absolutní URI na URI relativní k základní předponě URI. Příklad najdete v části Vytvoření URI relativního k základní předponě URI.
RegisterLocationChangingHandler Zaregistruje obslužnou rutinu pro zpracování příchozích navigačních událostí. Volání NavigateTo vždy vyvolá obsluhu.
GetUriWithQueryParameter Vrátí identifikátor URI vytvořený aktualizací NavigationManager.Uri s jedním přidaným, aktualizovaným nebo odebraným parametrem. Další informace naleznete v části Řetězce dotazů.
Člen Description
Uri Získá aktuální absolutní identifikátor URI.
BaseUri Získá základní identifikátor URI (s koncovým lomítkem), který lze připojit na začátek relativních cest URI k vytvoření absolutního identifikátoru URI. Obvykle BaseUri odpovídá href atributu elementu dokumentu <base> (umístění <head> obsahu).
NavigateTo Přejde na zadané URI. Pokud forceLoad je false:
  • Vylepšená navigace je k dispozici na aktuální adrese URL, Blazorje aktivována vylepšená navigace.
  • Blazor V opačném případě se pro požadovanou adresu URL znovu načte celá stránka.
Pokud forceLoad je true:
  • Směrování na straně klienta se vynechá.
  • Prohlížeč je nucen načíst novou stránku ze serveru bez ohledu na to, jestli je identifikátor URI obvykle zpracován interaktivním směrovačem na straně klienta.

Další informace najdete v části Rozšířená navigace a zpracování formulářů.

Pokud replace je true, aktuální identifikátor URI v historii prohlížeče se nahradí místo přidání nového identifikátoru URI do zásobníku historie.

LocationChanged Událost, která se aktivuje po změně polohy navigace. Další informace najdete v části Změny polohy.
ToAbsoluteUri Převede relativní identifikátor URI na absolutní identifikátor URI.
ToBaseRelativePath Na základě základního URI aplikace převádí absolutní URI na URI relativní k základní předponě URI. Příklad najdete v části Vytvoření URI relativního k základní předponě URI.
RegisterLocationChangingHandler Zaregistruje obslužnou rutinu pro zpracování příchozích navigačních událostí. Volání NavigateTo vždy vyvolá obsluhu.
GetUriWithQueryParameter Vrátí identifikátor URI vytvořený aktualizací NavigationManager.Uri s jedním přidaným, aktualizovaným nebo odebraným parametrem. Další informace naleznete v části Řetězce dotazů.
Člen Description
Uri Získá aktuální absolutní identifikátor URI.
BaseUri Získá základní identifikátor URI (s koncovým lomítkem), který lze připojit na začátek relativních cest URI k vytvoření absolutního identifikátoru URI. Obvykle BaseUri odpovídá href atributu elementu dokumentu <base> (umístění <head> obsahu).
NavigateTo Přejde na zadané URI. Pokud forceLoad je true:
  • Směrování na straně klienta se vynechá.
  • Prohlížeč je nucen načíst novou stránku ze serveru bez ohledu na to, jestli je identifikátor URI obvykle zpracován směrovačem na straně klienta.
Pokud replace je true, aktuální identifikátor URI v historii prohlížeče se nahradí místo přidání nového identifikátoru URI do zásobníku historie.
LocationChanged Událost, která se aktivuje po změně polohy navigace. Další informace najdete v části Změny polohy.
ToAbsoluteUri Převede relativní identifikátor URI na absolutní identifikátor URI.
ToBaseRelativePath Na základě základního URI aplikace převádí absolutní URI na URI relativní k základní předponě URI. Příklad najdete v části Vytvoření URI relativního k základní předponě URI.
RegisterLocationChangingHandler Zaregistruje obslužnou rutinu pro zpracování příchozích navigačních událostí. Volání NavigateTo vždy vyvolá obsluhu.
GetUriWithQueryParameter Vrátí identifikátor URI vytvořený aktualizací NavigationManager.Uri s jedním přidaným, aktualizovaným nebo odebraným parametrem. Další informace naleznete v části Řetězce dotazů.
Člen Description
Uri Získá aktuální absolutní identifikátor URI.
BaseUri Získá základní identifikátor URI (s koncovým lomítkem), který lze připojit na začátek relativních cest URI k vytvoření absolutního identifikátoru URI. Obvykle BaseUri odpovídá href atributu elementu dokumentu <base> (umístění <head> obsahu).
NavigateTo Přejde na zadané URI. Pokud forceLoad je true:
  • Směrování na straně klienta se vynechá.
  • Prohlížeč je nucen načíst novou stránku ze serveru bez ohledu na to, jestli je identifikátor URI obvykle zpracován směrovačem na straně klienta.
Pokud replace je true, aktuální identifikátor URI v historii prohlížeče se nahradí místo přidání nového identifikátoru URI do zásobníku historie.
LocationChanged Událost, která se aktivuje po změně polohy navigace. Další informace najdete v části Změny polohy.
ToAbsoluteUri Převede relativní identifikátor URI na absolutní identifikátor URI.
ToBaseRelativePath Na základě základního URI aplikace převádí absolutní URI na URI relativní k základní předponě URI. Příklad najdete v části Vytvoření URI relativního k základní předponě URI.
GetUriWithQueryParameter Vrátí identifikátor URI vytvořený aktualizací NavigationManager.Uri s jedním přidaným, aktualizovaným nebo odebraným parametrem. Další informace naleznete v části Řetězce dotazů.
Člen Description
Uri Získá aktuální absolutní identifikátor URI.
BaseUri Získá základní identifikátor URI (s koncovým lomítkem), který lze připojit na začátek relativních cest URI k vytvoření absolutního identifikátoru URI. Obvykle BaseUri odpovídá href atributu elementu dokumentu <base> (umístění <head> obsahu).
NavigateTo Přejde na zadané URI. Pokud forceLoad je true:
  • Směrování na straně klienta se vynechá.
  • Prohlížeč je nucen načíst novou stránku ze serveru bez ohledu na to, jestli je identifikátor URI obvykle zpracován směrovačem na straně klienta.
LocationChanged Událost, která se aktivuje po změně polohy navigace.
ToAbsoluteUri Převede relativní identifikátor URI na absolutní identifikátor URI.
ToBaseRelativePath Na základě základního URI aplikace převádí absolutní URI na URI relativní k základní předponě URI. Příklad najdete v části Vytvoření URI relativního k základní předponě URI.

Změny umístění

LocationChanged Pro událost LocationChangedEventArgs poskytuje následující informace o navigačních událostech:

Následující komponenta:

  • Po výběru tlačítka přejde na komponentu aplikace Counter (Counter.razor) pomocí NavigateTo.
  • Zpracovává událost o změně umístění tím, že se přihlásí k odběru NavigationManager.LocationChanged.
    • Metoda HandleLocationChanged je odpojena, když je metoda Dispose volána architekturou. Odpojením metody se umožní odstranění nepoužívaných dat komponenty.

    • Implementace protokolovacího nástroje zaznamená při výběru tlačítka následující informace:

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

Další informace o likvidaci komponent naleznete v tématu ASP.NET Core Razor likvidace komponent.

V případě přesměrování při vykreslování na straně statického serveru (static SSR) NavigationManager se spoléhá na vyvolání NavigationException zachyceného architekturou, která chybu převede na přesměrování. Kód, který existuje po volání NavigateTo , není volána. Při použití sady Visual Studio se ladicí program přeruší na výjimce, což vyžaduje zrušení zaškrtnutí políčka Break, pokud je tento typ výjimky zpracován uživatelem v uživatelském rozhraní sady Visual Studio, aby se zabránilo zastavení ladicího programu pro budoucí přesměrování.

Vlastnost MSBuild nastavenou <BlazorDisableThrowNavigationException> v souboru projektu aplikace můžete použít k true vyjádření souhlasu, aby se už nevyvolá .NavigationException Kód za voláním, který se NavigateTo má spustit, i když předtím nespustí. Toto chování je ve výchozím nastavení povolené v šabloně projektu .NET 10 nebo novější Blazor Web App :

<BlazorDisableThrowNavigationException>true</BlazorDisableThrowNavigationException>

Poznámka:

V .NET 10 nebo novějším můžete vyjádřit výslovný souhlas s tím, že NavigationException v souboru projektu aplikace nastavíte <BlazorDisableThrowNavigationException> vlastnost true MSBuild. Pokud chcete využít novou vlastnost a chování nástroje MSBuild, upgradujte aplikaci na .NET 10 nebo novější.

Nenalezena odpověď

NavigationManager poskytuje metodu NotFound pro zpracování scénářů, kdy se požadovaný prostředek nenašel během vykreslování na straně statického serveru (statického SSR) nebo globálního interaktivního vykreslování:

  • Statické rozhraní SSR: Volání NavigationManager.NotFound nastaví stavový kód HTTP na 404.

  • Interaktivní vykreslování: Signalizuje Blazor směrovač (Router součást) pro vykreslení obsahu Nenalezena.

  • Streamovací vykreslování: Pokud je vylepšená navigace aktivní, streamovací vykreslování zobrazuje nezobrazený obsah bez opětovného načtení stránky. Pokud je vylepšená navigace blokovaná, rámec přesměruje na stránku s obsahem "Stránka nenalezena" s aktualizací stránky.

Poznámka:

Následující diskuze uvádí, že komponentu Nenalezena Razor lze přiřadit k parametru RouterNotFoundPage komponenty. Parametr funguje ve spolupráci s NavigationManager.NotFound a je podrobněji popsán dále v této sekci.

Vykreslování streamování může vykreslovat pouze komponenty, které mají trasu NotFoundPage , například přiřazení (NotFoundPage="...") nebo přiřazení stránky se stavovým kódem, které znovu spustí přiřazení middlewarové stránky (UseStatusCodePagesWithReExecute). DefaultNotFound Obsah 404 ("Not foundprostý text) nemá trasu, takže se nedá použít při vykreslování streamování.

Poznámka:

Fragment vykreslení nenalezena (<NotFound>...</NotFound>) není v .NET 10 nebo novějším podporovaný.

NavigationManager.NotFound Vykreslování obsahu používá následující, bez ohledu na to, jestli se odpověď spustila nebo ne (v pořadí):

  • Pokud NotFoundEventArgs.Path je nastavená, vykreslujte obsah přiřazené stránky.
  • Pokud Router.NotFoundPage je nastavená, vykreslujte přiřazenou stránku.
  • Stránka Se stavovým kódem znovu spustí middlewarovou stránku( pokud je nakonfigurovaná).
  • Žádná akce není-li přijata žádná z předchozích přístupů.

Middleware pro opětovné spuštění stavových kódů má přednost při řešení problémů se směrováním adres URL v prohlížeči, jako je například nesprávná adresa URL zadaná do adresního řádku prohlížeče nebo výběr odkazu, který nemá v aplikaci žádný koncový bod.

Když se zavolá NavigationManager.NotFound a komponenta se vykreslí staticky (statická SSR), označí se odpověď stavovým kódem 404.

@page "/render-not-found-ssr"
@inject NavigationManager Navigation

@code {
    protected override void OnInitialized()
    {
        Navigation.NotFound();
    }
}

Pokud chcete poskytnout obsah pro globální interaktivní vykreslování, použijte stránku Nenalezeno (komponenta Razor).

Poznámka:

Šablona Blazor projektu obsahuje NotFound.razor stránku. Tato stránka se automaticky zobrazí při každém NavigationManager.NotFound zavolání, což umožňuje zpracovat chybějící cesty s konzistentním uživatelským prostředím.

Pages/NotFound.razor:

@page "/not-found"
@layout MainLayout

<h3>Not Found</h3>
<p>Sorry, the content you are looking for does not exist.</p>

Komponenta NotFound je přiřazena k parametru NotFoundPage směrovače. NotFoundPage podporuje směrování, které lze použít v rámci middlewaru pro opětovné provádění stránek stavových kódů, včetně ne-middlewaruBlazor.

V následujícím příkladu je předchozí komponenta NotFound umístěna ve složce aplikace Pages a je předána parametru NotFoundPage.

<Router AppAssembly="@typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
</Router>

Když se komponenta vykreslí pomocí globálního interaktivního režimu vykreslení, volání NavigationManager.NotFound signalizuje Blazor směrovači, aby vykreslilo NotFound komponentu.

@page "/render-not-found-interactive"
@inject NavigationManager Navigation

@if (RendererInfo.IsInteractive)
{
    <button @onclick="TriggerNotFound">Trigger Not Found</button>
}

@code {
    private void TriggerNotFound()
    {
        Navigation.NotFound();
    }
}

Událost OnNotFound můžete použít pro oznámení, když je vyvolána NavigationManager.NotFound. Událost se aktivuje pouze při NavigationManager.NotFound zavolání, nikoli pro jakoukoli odpověď 404. Například nastavení HttpContextAccessor.HttpContext.Response.StatusCode na 404 nevyvolá NavigationManager.NotFound/OnNotFound.

Aplikace, které implementují vlastní směrovač, mohou také používat NavigationManager.NotFound. Vlastní směrovač může vykreslit obsah nenalezena ze dvou zdrojů v závislosti na stavu odpovědi:

  • Bez ohledu na stav odpovědi může cesta k opětovnému spuštění stránky použít předáním UseStatusCodePagesWithReExecutedo:

    app.UseStatusCodePagesWithReExecute(
        "/not-found", createScopeForStatusCodePages: true);
    
  • Po spuštění odpovědi je možné ji použít tak, NotFoundEventArgs.Path že se přihlásíte k odběru OnNotFoundEvent směrovače:

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

V následujícím příkladu pro komponenty, které přijímají interaktivní vykreslování na straně serveru (interaktivní SSR), se vlastní obsah vykresluje v závislosti na tom, kde je OnNotFound voláno. Pokud se událost aktivuje následující Movie komponentou, když se při inicializaci komponenty nenajde video, vlastní zpráva uvádí, že požadovaný film nebyl nalezen. Pokud je událost aktivována komponentou User v následujícím příkladu, jiná zpráva uvádí, že uživatel nebyl nalezen.

Následující NotFoundContext služba spravuje kontext a zprávu o tom, kdy se obsah nenašel komponentami.

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

Služba je zaregistrovaná v souboru na straně Program serveru:

builder.Services.AddScoped<NotFoundContext>();

Stránka NotFound vloží NotFoundContext a zobrazí nadpis a zprávu.

Pages/NotFound.razor:

@page "/not-found"
@layout MainLayout
@inject NotFoundContext NotFoundContext

<h3>@NotFoundContext.Heading</h3>
<div>
    <p>@NotFoundContext.Message</p>
</div>

Komponenta Routes (Routes.razor) nastaví komponentu NotFound jako stránku Nenalezena prostřednictvím parametru NotFoundPage :

<Router AppAssembly="typeof(Program).Assembly" NotFoundPage="typeof(Pages.NotFound)">
    ...
</Router>

V následujících ukázkových komponentách:

  • Služba NotFoundContext se vloží spolu s NavigationManager.
  • V OnInitializedAsync je HandleNotFound obslužná rutina události přiřazená k události OnNotFound. HandleNotFound volá NotFoundContext.UpdateContext pro nastavení nadpisu a zprávy pro obsah Nenalezený v komponentě NotFound.
  • Komponenty by normálně používaly ID z parametru trasy k získání videa nebo uživatele z úložiště dat, jako je například databáze. V následujících příkladech se nevrátí žádná entita (null) pro simulaci toho, co se stane, když se entita nenajde.
  • Pokud není vrácena žádná entita OnInitializedAsync, je volána NavigationManager.NotFound, která následně vyvolá událost OnNotFound a obsluhu události HandleNotFound. Směrovač zobrazí obsah nenalezený.
  • Metoda HandleNotFound je odpojena při likvidaci komponenty v IDisposable.Dispose.

Movie součást (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 součást (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; }
    }
}

Pokud chcete získat přístup k předchozím komponentám v místní ukázce pomocí testovací aplikace, vytvořte položky v NavMenu komponentě (NavMenu.razor) pro přístup k komponentám Movie a User komponentám. ID entity předaná jako parametry trasy jsou v následujícím příkladu simulované hodnoty, které nemají žádný efekt, protože nejsou skutečně používány komponentami, které simulují, že film nebo uživatel nejsou nalezeni.

V 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>

Vylepšená navigace a zpracování formulářů

Tato sekce se vztahuje na Blazor Web Apps.

Blazor Web Appjsou schopné dvou typů trasování pro navigaci na stránkách a zpracování požadavků formulářů:

  • Normální navigace (navigace napříč dokumenty): Pro adresu URL požadavku se aktivuje opětovné načtení celé stránky.
  • Vylepšená navigace (navigace ve stejném dokumentu): Blazor zachytí požadavek a místo toho provede fetch. Blazor pak vloží obsah odpovědi do modelu DOM stránky. BlazorVylepšená navigace a zpracování formulářů se vyhýbají nutnosti znovu načítat celou stránku a zachovávají více stavu stránky, takže se stránky načítají rychleji, obvykle bez ztráty pozice posouvání uživatele na stránce.

Vylepšená navigace je dostupná v případech:

  • Skript Blazor Web App (blazor.web.js) se používá, nikoli Blazor Server skript (blazor.server.js) ani Blazor WebAssembly skript (blazor.webassembly.js).
  • Tato funkce není explicitně zakázaná.
  • Cílová adresa URL se nachází v prostoru vnitřního základního identifikátoru URI (základní cesta aplikace) a atribut data-enhance-nav není pro odkaz na stránku nastaven na false.

Pokud je povolené směrování na straně serveru a vylepšená navigace, budou obslužné rutiny pro změnu umístění vyvolány pouze pro programovou navigaci iniciovanou z interaktivního modulu runtime. V budoucích verzích můžou další typy navigace, například sledování odkazu, vyvolat také obslužné rutiny pro změnu umístění.

Když dojde k rozšířené navigaci, LocationChanged obslužné rutiny událostí zaregistrované v Interaktivním Serveru a modulu runtime WebAssembly se obvykle vyvolávají. Existují případy, kdy měniče polohy nemusí zaznamenat vylepšenou navigaci. Uživatel může například přepnout na jinou stránku, než bude k dispozici interaktivní běhové prostředí. Proto je důležité, aby logika aplikace nespoléhala na vyvolání obslužné rutiny změny umístění, protože neexistuje žádná záruka provádění obslužné rutiny.

Při volání NavigateTo:

  • Pokud forceLoad je false, což je výchozí:
    • Vylepšená navigace je k dispozici na aktuální adrese URL, Blazorje aktivována vylepšená navigace.
    • Blazor V opačném případě se pro požadovanou adresu URL znovu načte celá stránka.
  • Pokud forceLoad je true: Blazor provede obnovení celé stránky pro požadovanou adresu URL bez ohledu na to, zda je vylepšená navigace k dispozici, nebo ne.

Aktuální stránku můžete aktualizovat voláním NavigationManager.Refresh(bool forceLoad = false), která vždy provádí vylepšenou navigaci, pokud je k dispozici. Pokud není vylepšená navigace dostupná, Blazor provede opětovné načtení celé stránky.

Navigation.Refresh();

Předejte true parametru forceLoad , aby se zajistilo, že se vždy provede opětovné načítání celé stránky, i když je k dispozici vylepšená navigace:

Navigation.Refresh(true);

Vylepšená navigace je ve výchozím nastavení povolená, ale lze ji řídit hierarchicky a na základě odkazu pomocí atributu data-enhance-nav HTML.

Následující příklady zakazují rozšířenou navigaci:

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

Pokud je cílem nekoncovýBlazor bod, rozšířená navigace se nepoužije a JavaScript na straně klienta opakovaně načte celou stránku. Tím se zajistí, že rámec nebude zmateno ohledně externích stránek, které by se neměly připojovat k existující stránce.

Pokud chcete povolit rozšířené zpracování formulářů, přidejte Enhance parametr do EditForm formulářů nebo data-enhance atributu do formulářů HTML (<form>):

<EditForm ... Enhance ...>
    ...
</EditForm>
<form ... data-enhance ...>
    ...
</form>

Vylepšené zpracování formulářů není hierarchické a nepřenáší se do podřízených formulářů.

Nepodporováno: Nelze nastavit rozšířenou navigaci na nadřazený prvek formuláře, aby byla rozšířená navigace platná pro formulář.

<div ... data-enhance ...>
    <form ...>
        <!-- NOT enhanced -->
    </form>
</div>

Vylepšené formulářové příspěvky fungují pouze s Blazor koncovými body. Publikování rozšířeného formuláře na jiný než Blazor koncový bod způsobí chybu.

Zakázání rozšířené navigace:

  • Pro odstranění EditForm parametru z elementu formuláře Enhance (nebo jeho nastavení na false: Enhance="false").
  • Pro HTML <form>odeberte data-enhance atribut z elementu formuláře (nebo ho nastavte na false: data-enhance="false").

BlazorVylepšená navigace a zpracování formulářů můžou zrušit dynamické změny v DOM, není-li aktualizovaný obsah součástí vykreslování na serveru. Chcete-li zachovat obsah elementu, použijte data-permanent atribut.

V následujícím příkladu se obsah elementu <div> dynamicky aktualizuje skriptem při načtení stránky:

<div data-permanent>
    ...
</div>

Jakmile Blazor bude spuštěn na klientovi, můžete použít událost enhancedload pro sledování rozšířených aktualizací stránky. To umožňuje opětovné použití změn v systému DOM, které mohly být vráceny vylepšenou aktualizací stránky.

Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));

Pokud chcete zakázat rozšířenou navigaci a zpracování formulářů globálně, podívejte se na ASP.NET CoreBlazor startup.

Vylepšená navigace se statickým vykreslováním na straně serveru (static SSR) vyžaduje při načítání JavaScriptu zvláštní pozornost. Další informace najdete v tématu ASP.NET Core Blazor JavaScript s vykreslováním na serveru (statické SSR).

Vytvořte URI vzhledem k předponě základního URI

Na základě základního URI ToBaseRelativePath převede absolutní URI na URI relativní k předponě základního URI.

Představte si následující příklad:

try
{
    baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
    ...
}

Pokud je https://localhost:8000základní identifikátor URI aplikace, získáte následující výsledky:

  • Výsledkem předání https://localhost:8000/segment v inputURI je baseRelativePath z segment.
  • Výsledkem předání https://localhost:8000/segment1/segment2 v inputURI je baseRelativePath z segment1/segment2.

Pokud základní identifikátor URI aplikace neodpovídá URI základnímu identifikátoru inputURI, je vyvoláno ArgumentException.

Předání https://localhost:8001/segment v inputURI vede k následující výjimce:

System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'

Rozhraní API historie prohlížeče NavigationManager používá k udržování stavu navigační historie spojeného s každou změnou umístění provedenou aplikací. Udržování stavu historie je zvláště užitečné ve scénářích externího přesměrování, například při ověřování uživatelů s externími poskytovateli identity. Další informace najdete v části Možnosti navigace.

Předat NavigationOptions k NavigateTo pro řízení následujících chování:

  • ForceLoad: Obejití klientského směrování a vynucení, aby prohlížeč načetl novou stránku ze serveru, bez ohledu na to, zda je identifikátor URI zpracován klientským přesměrovávačem. Výchozí hodnota je false.
  • ReplaceHistoryEntry: Nahradit aktuální položku ve stacku historie. Pokud false, připojte novou položku do historie. Výchozí hodnota je false.
  • HistoryEntryState: Získá nebo nastaví stav pro přidání k záznamu historie.
Navigation.NavigateTo("/path", new NavigationOptions
{
    HistoryEntryState = "Navigation state"
});

Další informace o získání stavu spojeného s položkou historie cíle při zpracování změn umístění najdete v části Zpracování/zabránění změnám umístění.

Řetězce dotazů

Pomocí atributu [SupplyParameterFromQuery] určete, že parametr komponenty pochází z řetězce dotazu.

Použijte atribut [SupplyParameterFromQuery] s atributem [Parameter] k určení, že parametr komponenty směrovatelné komponenty pochází z řetězce dotazu.

Poznámka:

Parametry komponenty mohou přijímat pouze hodnoty parametrů dotazu ve směrovatelných komponentách s využitím direktivy @page.

Pouze směrovatelné komponenty přímo přijímají parametry dotazu, aby se zabránilo převrácení toku informací shora dolů a aby pořadí zpracování parametrů bylo jasné, a to jak podle architektury, tak aplikace. Tento návrh zabraňuje drobným chybám v kódu aplikace, který byl napsán za předpokladu konkrétního pořadí zpracování parametrů. Můžete definovat vlastní kaskádové parametry nebo přímo přiřadit k běžným parametrům komponent, abyste mohli předávat hodnoty parametrů dotazu nesměrovatelným komponentám.

Parametry komponenty zadané z řetězce dotazu podporují následující typy:

  • bool, DateTime, , decimal, double, floatGuid, int, longstring.
  • Varianty předchozích typů s možnou hodnotou null
  • Pole předchozích typů, bez ohledu na to, zda jsou nulovatelné nebo nenulovatelné.

Správné kulturně invariantní formátování se použije pro daný typ (CultureInfo.InvariantCulture).

Zadejte vlastnost atributu [SupplyParameterFromQuery]Name pro použití názvu parametru dotazu, který se liší od názvu parametru komponenty. V následujícím příkladu je {COMPONENT PARAMETER NAME}název jazyka C# parametru komponenty . Pro zástupný symbol {QUERY PARAMETER NAME} je zadán jiný název parametru dotazu.

Na rozdíl od vlastností parametru komponenty ([Parameter]) mohou být vlastnosti [SupplyParameterFromQuery] označeny private kromě public.

[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
private string? {COMPONENT PARAMETER NAME} { get; set; }

Podobně jako vlastnosti komponentních parametrů ([Parameter]), jsou vlastnosti [SupplyParameterFromQuery] vždy vlastnostmi public ve verzích .NET 6/7. Počínaje .NET 8 nebo novějšími verzemi lze vlastnosti [SupplyParameterFromQuery] označit jako public nebo private.

[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }

V následujícím příkladu s adresou URL /search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman:

  • Vlastnost Filter se přeloží na scifi stars.
  • Vlastnost Page se přeloží na 3.
  • Pole Stars se vyplní z parametrů dotazu s názvem star (Name = "star") a přeloží na LeVar Burton a Gary Oldman.

Poznámka:

Parametry řetězce dotazu v následující směrovatelné komponentě stránky fungují také v nesměrovatelné komponentě bez direktivy @page (například Search.razor pro sdílenou Search komponentu použitou v jiných součástech).

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

Slouží GetUriWithQueryParameter k přidání, změně nebo odebrání jednoho nebo více parametrů dotazu na aktuální adrese URL:

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})

Pro předchozí příklad:

  • Zástupný {NAME} symbol určuje název parametru dotazu. Zástupný {VALUE} symbol určuje hodnotu jako podporovaný typ. Podporované typy jsou uvedeny dále v této části.
  • Řetězec je vrácen stejně jako aktuální adresa URL s jedním parametrem:
    • Přidání, pokud název parametru dotazu v aktuální adrese URL neexistuje.
    • Aktualizace na hodnotu zadanou v případě, že parametr dotazu existuje v aktuální adrese URL.
    • Byla odebrána, pokud je typ poskytnuté hodnoty null a hodnota je null.
  • Správné kulturně invariantní formátování se použije pro daný typ (CultureInfo.InvariantCulture).
  • Název a hodnota parametru dotazu jsou kódované adresou URL.
  • Všechny hodnoty s odpovídajícím názvem parametru dotazu se nahradí, pokud existuje více instancí typu.

Zavolejte GetUriWithQueryParameters pro vytvoření URI zkonstruovaného z Uri, ke kterému byly přidány, aktualizovány nebo odebrány více parametry. Pro každou hodnotu rámec používá value?.GetType() k určení typu za běhu pro každý parametr dotazu a vybere správné formátování nezávislé na národním prostředí. Architektura vyvolá chybu pro nepodporované typy.

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameters({PARAMETERS})

Zástupný {PARAMETERS} symbol je IReadOnlyDictionary<string, object>.

Předejte řetězec URI do GetUriWithQueryParameters, abyste vytvořili nový identifikátor URI z poskytnutého identifikátoru URI s přidanými, aktualizovanými nebo odstraněnými parametry. Pro každou hodnotu rámec používá value?.GetType() k určení typu za běhu pro každý parametr dotazu a vybere správné formátování nezávislé na národním prostředí. Architektura vyvolá chybu pro nepodporované typy. Podporované typy jsou uvedeny dále v této části.

@inject NavigationManager Navigation

...

Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
  • Zástupný prvek {URI} je URI, které může obsahovat řetězec dotazu nebo nemusí.
  • Zástupný {PARAMETERS} symbol je IReadOnlyDictionary<string, object>.

Podporované typy jsou stejné jako podporované typy omezení trasy:

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

Mezi podporované typy patří:

  • Varianty předchozích typů s možnou hodnotou null
  • Pole předchozích typů, bez ohledu na to, zda jsou nulovatelné nebo nenulovatelné.

Výstraha

Díky kompresi, která je ve výchozím nastavení povolená, se vyhněte vytváření zabezpečených (ověřených/autorizovaných) interaktivních komponent na straně serveru, které vykreslují data z nedůvěryhodných zdrojů. Mezi nedůvěryhodné zdroje patří parametry směrování, řetězce dotazů, data z JS interoperability a jakýkoli jiný zdroj dat, který může uživatel třetí strany řídit (databáze, externí služby). Pro další informace viz pokyny pro ASP.NET CoreBlazorSignalR a pokyny pro zmírnění rizik pro interaktivní vykreslování na straně serveru v ASP.NET CoreBlazor.

Nahrazení hodnoty parametru dotazu, pokud parametr existuje

Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
Aktuální adresa URL Vygenerovaná adresa 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

Přidejte parametr dotazu a hodnotu, pokud parametr neexistuje

Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
Aktuální adresa URL Vygenerovaná adresa 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

Odebrání parametru dotazu, pokud je hodnota parametru null

Navigation.GetUriWithQueryParameter("full name", (string)null)
Aktuální adresa URL Vygenerovaná adresa 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/

Přidání, aktualizace a odebrání parametrů dotazu

V následujícím příkladu:

  • Pokud je přítomen, name se odebere.
  • age je přidáno s hodnotou 25 (int), pokud není k dispozici. Pokud je k dispozici, age aktualizuje se na hodnotu 25.
  • eye color je přidána nebo aktualizována na hodnotu green.
Navigation.GetUriWithQueryParameters(
    new Dictionary<string, object?>
    {
        ["name"] = null,
        ["age"] = (int?)25,
        ["eye color"] = "green"
    })
Aktuální adresa URL Vygenerovaná adresa 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

Podpora výčtových hodnot

V následujícím příkladu:

  • full name je přidán nebo aktualizován na Morena Baccarin, jedna hodnota.
  • ping parametry jsou přidány nebo nahrazeny 35, 16, 87 a 240.
Navigation.GetUriWithQueryParameters(
    new Dictionary<string, object?>
    {
        ["full name"] = "Morena Baccarin",
        ["ping"] = new int?[] { 35, 16, null, 87, 240 }
    })
Aktuální adresa URL Vygenerovaná adresa 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

K navigaci s přidaným nebo upraveným řetězcem dotazu předejte vygenerovanou adresu URL NavigateTo.

Následující příklad volání:

Navigation.NavigateTo(
    Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));

Řetězec dotazu z požadavku se získává z vlastnosti NavigationManager.Uri.

@inject NavigationManager Navigation

...

var query = new Uri(Navigation.Uri).Query;

Pokud chcete parsovat parametry řetězce dotazu, jedním z přístupů je použít URLSearchParams s JavaScript (JS) interoperabilitou.

export createQueryString = (string queryString) => new URLSearchParams(queryString);

Další informace o izolaci JavaScriptu pomocí modulů JavaScriptu najdete v tématu Volání funkcí JavaScriptu z metod .NET v ASP.NET Core Blazor.

S použitím následujících přístupů s hashovaným (#) odkazem přejděte na pojmenovaný element. Trasy k prvkům v rámci komponenty a trasy k prvkům v externích komponentách používají kořenové relativní cesty. Úvodní lomítko (/) je volitelné.

Příklady pro každý z následujících přístupů ukazují navigaci na prvek s id a targetElement v komponentě Counter.

  • Ukotvení elementu (<a>) s href:

    <a href="/counter#targetElement">
    
  • NavLink komponenta s href:

    <NavLink href="/counter#targetElement">
    
  • NavigationManager.NavigateTo předání relativní adresy URL:

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

Následující příklad ukazuje navigaci na pojmenované nadpisy H2 v rámci komponenty a k externím komponentám.

V komponentách Home (Home.razor) a Counter (Counter.razor) umístěte následující značení na konec stávajícího značení komponent, které slouží jako cíle navigace. Vytvoří umělou svislou mezeru <div>, která demonstruje chování při posouvání v prohlížeči.

<div class="border border-info rounded bg-info" style="height:500px"></div>

<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>

Do aplikace přidejte následující FragmentRouting komponentu.

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

Řešení nebo zabránění změnám umístění

RegisterLocationChangingHandler zaregistruje obslužnou rutinu pro zpracování příchozích navigačních událostí. Kontext obslužné rutiny poskytovaný následujícími vlastnostmi LocationChangingContext :

Komponenta může v OnAfterRender{Async} metodě životního cyklu zaregistrovat několik obslužných rutin pro změnu umístění. Navigace vyvolá všechny obslužné rutiny pro změnu umístění zaregistrované v celé aplikaci (napříč více komponentami) a všechny interní navigace je spustí paralelně. Kromě obslužných rutin NavigateTo jsou vyvolány:

  • Při výběru interních odkazů, což jsou odkazy odkazující na adresy URL v základní cestě aplikace.
  • Při navigaci pomocí tlačítek vpřed a zpět v prohlížeči.

Obslužné rutiny se spouštějí pouze pro interní navigaci v aplikaci. Pokud uživatel vybere odkaz, který přejde na jiný web nebo změní adresní řádek na jiný web ručně, nespustí se obslužné rutiny pro změnu umístění.

Implementujte IDisposable a zrušte registraci registrovaných obslužných rutin k jejich odstranění. Další informace najdete v tématu odstranění komponenty ASP.NET Core Razor.

Důležité

Při zpracování změn umístění se nepokoušejte spouštět úlohy čištění DOM prostřednictvím interoperability JavaScriptu (JS). MutationObserver Použijte vzor na JS klientovi. Další informace najdete v tématu ASP.NET Core Blazor interoperabilita JavaScriptu (JSinterop).

V následujícím příkladu je obslužná rutina změny umístění registrována pro události navigace.

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

Vzhledem k tomu, že interní navigaci je možné zrušit asynchronně, může dojít k několika současně překrývajícím se voláním registrovaných handlerů. Například více volání obslužné rutiny může nastat, když uživatel rychle vybere tlačítko Zpět na stránce nebo vybere více odkazů před spuštěním navigace. Následuje souhrn asynchronní navigační logiky:

  • Pokud jsou zaregistrované nějaké obslužné rutiny pro změnu umístění, je veškerá navigace nejprve navrácena a poté opakovaně provedena, pokud nedojde ke zrušení navigace.
  • Pokud se provádějí překrývající se navigační požadavky, nejnovější požadavek vždy zruší dřívější požadavky, což znamená následující:
    • Aplikace může zacházet s několika výběry tlačítek zpět a vpřed jako s jedním výběrem.
    • Pokud uživatel vybere více odkazů před dokončením navigace, určuje poslední vybraný odkaz navigaci.

Další informace o předávání NavigationOptions do NavigateTo k ovládání položek a stavu zásobníku historie navigace naleznete v části Možnosti navigace.

Další příklad kódu naleznete NavigationManagerComponent v BasicTestApp (dotnet/aspnetcore referenční zdroj).

Poznámka:

Odkazy na referenční zdroj .NET v dokumentaci obvykle otevřou výchozí větev úložiště, která představuje aktuální vývoj další verze .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí mezi větvemi nebo značkami. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Komponenta NavigationLock zachytí navigační události, dokud je vykreslována, a efektivně "uzamkne" všechny dané navigace, dokud není rozhodnuto o pokračování nebo zrušení. Použijte NavigationLock, když lze zachycení navigace omezit na dobu životnosti komponenty.

NavigationLock parametry:

  • ConfirmExternalNavigation nastaví dialogové okno prohlížeče, které uživatele vyzve k potvrzení nebo zrušení externí navigace. Výchozí hodnota je false. Zobrazení potvrzovacího dialogového okna vyžaduje počáteční interakci uživatele se stránkou před aktivací externí navigace s adresou URL v adresovém řádku prohlížeče. Další informace o požadavku na interakci najdete v části Window: beforeunload událost.
  • OnBeforeInternalNavigation určuje zpětné volání pro interní navigační události.

V následující komponentě NavLock:

  • Než bude navigace https://www.microsoft.com úspěšná, musí uživatel potvrdit pokus o sledování odkazu na web společnosti Microsoft.
  • je volána, aby se zabránilo provedení navigace, pokud uživatel odmítne potvrdit navigaci prostřednictvím interop volání JavaScriptu (), které vytvoří dialogové okno .

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

Další příklad kódu naleznete v ConfigurableNavigationLock komponentě BasicTestApp (dotnet/aspnetcore referenční zdroj).

NavLink položky komponent lze dynamicky vytvářet z komponent aplikace prostřednictvím reflexe. Následující příklad ukazuje obecný přístup k dalšímu přizpůsobení.

Pro následující ukázku se pro komponenty aplikace používá konzistentní standardní zásady vytváření názvů:

  • Názvy souborů směrovatelných komponent používají velká písmena v Pascalově zápisu, například Pages/ProductDetail.razor.
  • Cesty k souborům směrovatelných komponent odpovídají jejich adresám URL v kebab case, přičemž pomlčky jsou umístěny mezi slovy v šabloně tras komponent. Například komponenta ProductDetail s šablonou trasy /product-detail (@page "/product-detail") je přístupná v prohlížeči na relativní adrese URL /product-detail.

† PascalCase (UpperCamelCase) je konvence pojmenovávání, která neobsahuje mezery ani interpunkci a u níž je první písmeno každého slova velké, včetně prvního slova.
{Kebab case je konvence pojmenování bez mezer a interpunkce, která používá malá písmena a pomlčky mezi slovy.

V kódu komponenty Razor (NavMenu) na výchozí stránce NavMenu.razor jsou komponenty Home přidány z kolekce:

<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 v @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);

Předchozí příklad neobsahuje následující stránky v vykresleného seznamu komponent:

  • Home page: Stránka je uvedena odděleně od automaticky generovaných odkazů, protože by se měla zobrazit v horní části seznamu a nastavit Match parametr.
  • Error stránka: Chybová stránka je přístupná pouze podle rámce a neměla by být uvedena v seznamu.

Pro ukázku předchozího kódu v ukázkové aplikaci získáte ukázkovou aplikaci Blazor Web App nebo Blazor WebAssembly.