Routing e navigazione in ASP.NET Core Blazor
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Questo articolo illustra come gestire Blazor il routing delle richieste di app e come usare il NavLink componente per creare collegamenti di spostamento.
Importante
Gli esempi di codice in questo articolo illustrano i metodi chiamati su Navigation
, che è un oggetto inserito NavigationManager in classi e componenti.
Routing statico e interattivo
Questa sezione si applica a Blazor Web Apps.
Se il prerendering è abilitato, il router (Blazor componente, Router
in <Router>
) esegue il routing statico verso i componenti durante il rendering statico lato server (SSR statico). Questo tipo di routing è denominato routing statico.
Quando viene assegnata una modalità di rendering interattiva al componente Routes
, il router Blazor diventa interattivo dopo SSR statico con routing statico sul server. Questo tipo di routing è denominato routing interattivo.
I router statici usano il routing degli endpoint e il percorso della richiesta HTTP per determinare quale componente eseguire il rendering. Quando il router diventa interattivo, usa l'URL del documento (l'URL nella barra degli indirizzi del browser) per determinare quale componente eseguire il rendering. Ciò significa che il router interattivo può modificare dinamicamente il componente di cui viene eseguito il rendering se l'URL del documento cambia dinamicamente in un altro URL interno valido e può farlo senza eseguire una richiesta HTTP per recuperare il contenuto di una nuova pagina.
Il routing interattivo impedisce anche il prerendering perché il nuovo contenuto della pagina non viene richiesto dal server tramite una normale richiesta di pagina. Per ulteriori informazioni, vedere Componenti ASP.NET Core di prerenderingRazor.
Modelli di route
Router il componente consente il routing ai componenti Razor ed è situato nel componente dell'app Routes
(Components/Routes.razor
).
Il componente Router consente ai componenti Razor di effettuare il routing. Il componente Router viene usato nel componente App
(App.razor
).
Quando un componente Razor (.razor
) con una @page
direttiva viene compilato, viene fornita una classe componente generata che RouteAttribute specifica il modello di route del componente.
All'avvio dell'app, l'assembly specificato come router AppAssembly
viene analizzato per raccogliere informazioni di route per i componenti dell'app che hanno un oggetto RouteAttribute.
In fase di esecuzione, il componente RouteView:
- Riceve il RouteData dal Router insieme a qualsiasi parametro di route.
- Esegue il rendering del componente specificato con il relativo layout, inclusi eventuali altri layout annidati.
Facoltativamente, specificare un DefaultLayout parametro con una classe di layout per i componenti che non specificano un layout con la @layout
direttiva . I modelli di progetto delBlazorframework specificano il MainLayout
componente (MainLayout.razor
) come layout predefinito dell'app. Per altre informazioni sui layout, vedere ASP.NET Layout coreBlazor.
I componenti supportano più modelli di route usando più @page
direttive. Il componente di esempio seguente viene caricato nelle richieste per /blazor-route
e /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>
Importante
Affinché gli URL vengano risolti correttamente, l'app deve includere un <base>
tag (posizione del <head>
contenuto) con il percorso di base dell'app specificato nell'attributo href
. Per altre informazioni, vedere Ospitare e distribuire ASP.NET Core Blazor.
Il Router non interagisce con i valori della stringa di query. Per usare le stringhe di query, vedere la sezione Stringhe di query.
In alternativa alla specifica del modello di route come stringa letterale con la direttiva @page
, è possibile definire modelli di route costanti con la direttiva @attribute
.
Nell'esempio seguente la @page
direttiva in un componente viene sostituita con la @attribute
direttiva e il modello di route basato su costante in Constants.CounterRoute
, che viene impostato altrove nell'app su "/counter
":
- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]
Nota
Con la versione di ASP.NET Core 5.0.1 e per eventuali versioni 5.x aggiuntive, il componente Router
include il parametro PreferExactMatches
impostato su @true
. Per altre informazioni, vedere Eseguire la migrazione da ASP.NET Core 3.1 a 5.0.
Concentrarsi su un elemento nella navigazione
Il componente FocusOnNavigate imposta il focus dell'interfaccia utente su un elemento basato su un selettore CSS dopo la navigazione da una pagina a un'altra.
<FocusOnNavigate RouteData="routeData" Selector="h1" />
Quando il componente Router passa a una nuova pagina, il componente FocusOnNavigate imposta lo stato attivo sull'intestazione di primo livello della pagina (<h1>
). Si tratta di una strategia comune per garantire che uno spostamento di pagina venga annunciato quando si usa un'utilità per la lettura dello schermo.
Fornire contenuto personalizzato quando il contenuto non viene trovato
Il Router componente consente all'app di specificare contenuto personalizzato se il contenuto non viene trovato per la route richiesta.
Impostare il contenuto personalizzato per il Router parametro del NotFound componente:
<Router ...>
...
<NotFound>
...
</NotFound>
</Router>
Gli elementi arbitrari sono supportati come contenuto del NotFound parametro, ad esempio altri componenti interattivi. Per applicare un layout predefinito al NotFound contenuto, vedere layout di ASP.NET CoreBlazor.
Importante
Blazor Web Appnon utilizzano il parametro NotFound (markup<NotFound>...</NotFound>
), ma il parametro è supportato† per garantire la compatibilità con le versioni precedenti al fine di evitare una modifica significativa nel framework. La pipeline middleware di ASP.NET Core lato server elabora le richieste sul server. Usare tecniche lato server per gestire richieste non valide.
†Supportato in questo contesto significa che l'inserimento del markup <NotFound>...</NotFound>
non comporta un'eccezione, ma l'uso del markup non produce effetti.
Per altre informazioni, incluso un approccio consigliato per la gestione delle richieste non valide, vedere ASP.NET Core Blazor modalità di rendering.
Indirizzare ai componenti da più assembly
Questa sezione si applica a Blazor Web Apps.
Usare il parametro AdditionalAssemblies del Router componente e il generatore di convenzioni dell'endpoint AddAdditionalAssemblies per individuare i componenti indirizzabili in assemblies aggiuntive. Le sottosezioni seguenti illustrano quando e come usare ogni API.
Instradamento statico
Per individuare componenti instradabili da assembly aggiuntivi per il rendering lato server statico (SSR statico), gli assembly devono essere resi noti al framework Blazor, anche se il router diventa in seguito interattivo per il rendering interattivo. Chiamare il metodo AddAdditionalAssemblies con gli assembly aggiuntivi collegati a MapRazorComponents nel file Program
del progetto server.
L'esempio seguente include i componenti instradabili nell'assembly BlazorSample.Client
del progetto usando il file del progetto _Imports.razor
.
app.MapRazorComponents<App>()
.AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
Nota
Le indicazioni precedenti si applicano anche negli scenari della libreria di classi dei componenti. Altre indicazioni importanti per le librerie di classi e SSR statico sono disponibili in librerie di classi ASP.NET Core Razor (RCL) con rendering statico lato server (SSR statico).
Routing interattivo
È possibile assegnare una modalità di rendering interattiva al Routes
componente (Routes.razor
) che rende il router interattivo dopo ssr Blazor statico e routing statico nel server. Ad esempio, <Routes @rendermode="InteractiveServer" />
assegna il rendering interattivo lato server (SSR interattivo) al componente Routes
. Il componente Router
eredita dal componente Routes
l'interactive server-side rendering (SSR interattivo). Il router diventa interattivo dopo il routing statico nel server.
Lo spostamento interno per il routing interattivo non comporta la richiesta di nuovo contenuto della pagina dal server. Di conseguenza, il prerendering non si verifica per le richieste di pagina interne. Per ulteriori informazioni, vedere Componenti di ASP.NET Core prerenderizzatiRazor.
Se il componente Routes
è definito nel progetto server, il parametro AdditionalAssemblies del componente Router
deve includere l'assembly del progetto .Client
. Ciò consente al router di funzionare correttamente quando ne viene eseguito il rendering in modo interattivo.
Nell'esempio seguente il Routes
componente si trova nel progetto server e il _Imports.razor
file del BlazorSample.Client
progetto indica l'assembly in cui cercare i componenti instradabili:
<Router
AppAssembly="..."
AdditionalAssemblies="[ typeof(BlazorSample.Client._Imports).Assembly ]">
...
</Router>
Gli assembly aggiuntivi vengono analizzati oltre all'assembly specificato in AppAssembly.
Nota
Le indicazioni precedenti si applicano anche negli scenari della libreria di classi dei componenti.
In alternativa, i componenti instradabili esistono solo nel .Client
progetto con WebAssembly interattivo o rendering automatico applicati e il Routes
componente è definito nel .Client
progetto, non nel progetto server. In questo caso, non sono presenti assembly esterni con componenti instradabili, quindi non è necessario specificare un valore per AdditionalAssemblies.
Questa sezione si applica alle Blazor Server app.
Usare il Router parametro del AdditionalAssemblies componente e il generatore AddAdditionalAssemblies di convenzioni dell'endpoint per individuare i componenti instradabili in assembly aggiuntivi.
Nell'esempio seguente è Component1
un componente instradabile definito in una libreria di classi di componenti a cui si fa riferimento denominata ComponentLibrary
:
<Router
AppAssembly="..."
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }">
...
</Router>
Gli assembly aggiuntivi vengono analizzati oltre all'assembly specificato in AppAssembly.
Parametri di route
Il router usa i parametri di route per popolare i parametri del componente corrispondenti con lo stesso nome. I nomi dei parametri di route non fanno distinzione tra maiuscole e minuscole. Nell'esempio seguente il text
parametro assegna il valore del segmento di route alla proprietà del Text
componente. Quando viene effettuata una richiesta per /route-parameter-1/amazing
, il rendering del contenuto viene eseguito come 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; }
}
Sono supportati parametri facoltativi. Nell'esempio seguente il parametro facoltativo text
assegna il valore del segmento di route alla proprietà Text
del componente. Se il segmento non è presente, il valore di Text
viene impostato su fantastic
.
I parametri facoltativi non sono supportati. Nell'esempio seguente vengono applicate due @page
direttive . La prima direttiva consente la navigazione verso il componente senza un parametro. La seconda direttiva assegna il valore del {text}
parametro di route alla proprietà del Text
componente.
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";
}
}
Quando viene usato il OnInitialized{Async}
metodo del ciclo di vita anziché ilOnParametersSet{Async}
metodo del ciclo di vita, l'assegnazione predefinita della Text
proprietà a fantastic
non si verifica se l'utente si sposta all'interno dello stesso componente. Ad esempio, questa situazione si verifica quando l'utente passa da /route-parameter-2/amazing
a /route-parameter-2
. Quando l'istanza del componente persiste e accetta nuovi parametri, il OnInitialized
metodo non viene richiamato di nuovo.
Nota
I parametri di route non funzionano con i valori della stringa di query. Per usare le stringhe di query, vedere la sezione Stringhe di query.
Vincoli della route
Un vincolo di route applica la corrispondenza dei tipi in un segmento di route a un componente.
Nell'esempio seguente, la route verso il componente User
corrisponde solo se:
- Un
Id
segmento di route è presente nell'URL della richiesta. - Il
Id
segmento è un tipo integer (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; }
}
Nota
I vincoli di route non funzionano con i valori della stringa di query. Per usare le stringhe di query, vedere la sezione Stringhe di query.
Sono disponibili i vincoli di route illustrati nella tabella seguente. Per i vincoli di route che corrispondono alla cultura invariante, vedere l'avviso di seguito alla tabella per ulteriori informazioni.
Vincolo | Esempio | Esempi di corrispondenze | Invariante Cultura abbinamento |
---|---|---|---|
bool |
{active:bool} |
true , FALSE |
No |
datetime |
{dob:datetime} |
2016-12-31 , 2016-12-31 7:32pm |
Sì |
decimal |
{price:decimal} |
49.99 , -1,000.01 |
Sì |
double |
{weight:double} |
1.234 , -1,001.01e8 |
Sì |
float |
{weight:float} |
1.234 , -1,001.01e8 |
Sì |
guid |
{id:guid} |
00001111-aaaa-2222-bbbb-3333cccc4444 , {00001111-aaaa-2222-bbbb-3333cccc4444} |
No |
int |
{id:int} |
123456789 , -123456789 |
Sì |
long |
{ticks:long} |
123456789 , -123456789 |
Sì |
nonfile |
{parameter:nonfile} |
Non BlazorSample.styles.css , non favicon.ico |
Sì |
Avviso
I vincoli di route che verificano l'URL e vengono convertiti in un tipo CLR, come int
o DateTime, utilizzano sempre la cultura invariante. Questi vincoli assumono che l'URL sia non localizzabile.
I vincoli di route funzionano anche con parametri facoltativi. Nell'esempio Id
seguente è obbligatorio, ma Option
è un parametro di route booleano facoltativo.
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; }
}
Evitare l'acquisizione di file in un parametro del percorso
Il modello di route seguente acquisisce inavvertitamente percorsi di asset statici nel parametro di route facoltativo (Optional
). Ad esempio, il foglio di stile dell'app (.styles.css
) viene catturato, interrompendo gli stili dell'app:
@page "/{optional?}"
...
@code {
[Parameter]
public string? Optional { get; set; }
}
Per limitare un parametro di route all'acquisizione di percorsi non di file, usare il :nonfile
vincolo nel modello di route:
@page "/{optional:nonfile?}"
Routing con URL che contengono punti
Un modello predefinito di route lato server presuppone che se l'ultimo segmento di un URL di richiesta contiene un punto (.
) richiede un file. Ad esempio, l'URL /example/some.thing
relativo viene interpretato dal router come richiesta di un file denominato some.thing
. Senza una configurazione aggiuntiva, un'app restituisce una risposta 404 - Non trovato se some.thing
è stato progettato per instradare a un componente con una @page
direttiva ed some.thing
è un valore del parametro di route. Per usare una route con uno o più parametri che contengono un punto, l'app deve configurare la route con un modello personalizzato.
Si consideri il componente seguente Example
che può ricevere un parametro di route dall'ultimo segmento dell'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; }
}
Per consentire all'app Server di una Blazor WebAssemblysoluzione ospitata di instradare la richiesta con un punto nel param
parametro di route, aggiungere nel Program
file un modello di route di fallback con il parametro facoltativo:
app.MapFallbackToFile("/example/{param?}", "index.html");
Per configurare un'app Blazor Server per instradare la richiesta che include un punto nel parametro di route param
, aggiungere un modello di route di pagina di fallback con il parametro facoltativo nel file Program
:
app.MapFallbackToPage("/example/{param?}", "/_Host");
Per altre informazioni, vedere Routing in ASP.NET Core.
Per consentire all'app Server di una soluzione ospitata Blazor WebAssemblydi instradare la richiesta con un punto nel param
parametro di route, aggiungere un modello di route di file di fallback con il parametro facoltativo in Startup.Configure
.
Startup.cs
:
endpoints.MapFallbackToFile("/example/{param?}", "index.html");
Per configurare un'app Blazor Server affinché instradi la richiesta con un punto nel parametro del percorso param
, aggiungere un modello di route di pagina di fallback con il parametro facoltativo in Startup.Configure
.
Startup.cs
:
endpoints.MapFallbackToPage("/example/{param?}", "/_Host");
Per altre informazioni, vedere Routing in ASP.NET Core.
Parametri di route universale
I parametri di route catch-all, che acquisiscono i percorsi attraverso più limiti di cartella, sono supportati nei componenti.
I parametri di route catch-all sono:
- Denominato in modo che corrisponda al nome del segmento di route. La denominazione non fa distinzione tra maiuscole e minuscole.
- Tipo
string
. Il framework non fornisce il cast automatico. - Alla fine dell'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; }
}
Per l'URL /catch-all/this/is/a/test
con un modello di route di /catch-all/{*pageRoute}
, il valore di PageRoute
è impostato su this/is/a/test
.
Le barre e i segmenti del percorso acquisito vengono decodificati. Per un modello di route di /catch-all/{*pageRoute}
, l'URL /catch-all/this/is/a%2Ftest%2A
restituisce this/is/a/test*
.
Helper di URI e dello stato di navigazione
Usare NavigationManager per gestire gli URI e lo spostamento nel codice C#. NavigationManager fornisce l'evento e i metodi illustrati nella tabella seguente.
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con una barra finale) che può essere anteposto ai percorsi URI relativi per produrre un URI assoluto. In genere, BaseUri corrisponde all'attributo href dell'elemento del <base> documento (posizione del <head> contenuto). |
NavigateTo | Passa all'URI specificato. Se forceLoad è false :
forceLoad è true :
Per altre informazioni, vedere la sezione Navigazione avanzata e gestione dei moduli. Se |
LocationChanged | Evento che viene attivato quando la posizione di navigazione è cambiata. Per altre informazioni, vedere la sezione Modifiche alla posizione . |
ToAbsoluteUri | Converte un URI relativo in un URI assoluto. |
ToBaseRelativePath | In base all'URI di base dell'app, converte un URI assoluto in un URI relativo al prefisso dell'URI di base. Per un esempio, vedere la sezione Produrre un URI relativo al prefisso dell'URI di base. |
RegisterLocationChangingHandler |
Registra un gestore per elaborare gli eventi di navigazione in arrivo. La chiamata NavigateTo richiama sempre il gestore. |
GetUriWithQueryParameter | Restituisce un URI costruito aggiornando NavigationManager.Uri con un singolo parametro aggiunto, aggiornato o rimosso. Per ulteriori informazioni, vedere la sezione stringhe di query. |
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con una barra finale) che può essere anteposto ai percorsi URI relativi per ottenere un URI assoluto. In genere, BaseUri corrisponde all'attributo href dell'elemento del <base> documento (posizione del <head> contenuto). |
NavigateTo | Passa all'URI specificato. Se forceLoad è true :
replace è true , l'URI corrente nella cronologia del browser viene sostituito invece di eseguire il push di un nuovo URI nello stack di cronologia. |
LocationChanged | Evento che viene attivato quando la posizione di navigazione è cambiata. Per altre informazioni, vedere la sezione Modifiche alla posizione . |
ToAbsoluteUri | Converte un URI relativo in un URI assoluto. |
ToBaseRelativePath | In base all'URI di base dell'app, converte un URI assoluto in un URI relativo al prefisso dell'URI di base. Per un esempio, vedere la sezione Produrre un URI relativo al prefisso dell'URI di base. |
RegisterLocationChangingHandler |
Registra un gestore per elaborare gli eventi di spostamento in ingresso. La chiamata NavigateTo richiama sempre il gestore. |
GetUriWithQueryParameter | Restituisce un URI costruito aggiornando NavigationManager.Uri con un singolo parametro aggiunto, aggiornato o rimosso. Per altre informazioni, vedere la sezione Stringhe di interrogazione. |
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con una barra finale) che può essere anteposto ai percorsi URI relativi per produrre un URI assoluto. In genere, BaseUri corrisponde all'attributo href dell'elemento del <base> documento (posizione del <head> contenuto). |
NavigateTo | Naviga all'URI specificato. Se forceLoad è true :
replace è true , l'URI corrente nella cronologia del browser viene sostituito invece di eseguire il push di un nuovo URI nello stack di cronologia. |
LocationChanged | Un evento che viene generato quando la posizione di navigazione cambia. Per altre informazioni, vedere la sezione Modifiche alla posizione . |
ToAbsoluteUri | Converte un URI relativo in un URI assoluto. |
ToBaseRelativePath | In base all'URI di base dell'app, converte un URI assoluto in un URI relativo al prefisso dell'URI di base. Per un esempio, vedere la sezione Produrre un URI relativo al prefisso dell'URI di base. |
GetUriWithQueryParameter | Restituisce un URI costruito aggiornando NavigationManager.Uri con un singolo parametro aggiunto, aggiornato o rimosso. Per ulteriori informazioni, vedere la sezione Stringhe di query. |
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con uno slash finale) che può essere anteposto ai percorsi URI relativi per produrre un URI assoluto. In genere, BaseUri corrisponde all'attributo href dell'elemento del <base> documento (posizione del <head> contenuto). |
NavigateTo | Passa all'URI specificato. Se forceLoad è true :
|
LocationChanged | Evento che viene generato quando la posizione di navigazione è cambiata. |
ToAbsoluteUri | Converte un URI relativo in un URI assoluto. |
ToBaseRelativePath | In base all'URI di base dell'app, converte un URI assoluto in un URI relativo al prefisso dell'URI di base. Per un esempio, vedere la sezione Produrre un URI relativo al prefisso dell'URI di base. |
Modifiche alla posizione
Per l'evento LocationChanged, LocationChangedEventArgs fornisce le seguenti informazioni sugli eventi di navigazione:
- Location: URL del nuovo percorso.
-
IsNavigationIntercepted: se
true
, Blazor ha intercettato la navigazione dal browser. Sefalse
, NavigationManager.NavigateTo ha causato la navigazione.
Componente seguente:
- Passa al componente dell'app
Counter
(Counter.razor
) quando si seleziona un pulsante con NavigateTo. - Gestisce l'evento di cambiamento di posizione iscrivendosi a NavigationManager.LocationChanged.
Il
HandleLocationChanged
metodo viene scollegato quandoDispose
viene chiamato dal framework. Scollegare il metodo consente la garbage collection del componente.L'implementazione del logger registra le informazioni seguenti quando viene selezionato il pulsante:
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;
}
}
Per ulteriori informazioni sull'eliminazione dei componenti, vedere il
Navigazione avanzata e gestione dei moduli
Questa sezione si applica a Blazor Web Apps.
Blazor Web Apps è in grado di eseguire due tipi di routing per lo spostamento di pagine e le richieste di gestione dei moduli:
- Navigazione normale (spostamento tra documenti): viene attivato un ricaricamento a pagina intera per l'URL della richiesta.
- Spostamento avanzato (navigazione nello stesso documento): Blazor intercetta la richiesta ed esegue invece una
fetch
richiesta. Blazor applica quindi patch al contenuto della risposta nel DOM della pagina. BlazorLa gestione avanzata dei moduli e della navigazione evita la necessità di ricaricare una pagina intera e mantiene più dello stato della pagina, quindi le pagine vengono caricate più velocemente, in genere senza perdere la posizione di scorrimento dell'utente nella pagina.
La navigazione avanzata è disponibile quando:
- Lo Blazor Web App script (
blazor.web.js
) viene usato, non lo Blazor Server script (blazor.server.js
) o lo Blazor WebAssembly script (blazor.webassembly.js
). - La funzionalità non è esplicitamente disabilitata.
- L'URL di destinazione si trova all'interno dello spazio URI di base interno (percorso di base dell'app).
Se il routing sul lato server e la navigazione avanzata sono abilitati, i gestori di modifica della posizione vengono richiamati solo per la navigazione a livello di codice avviata da un runtime interattivo. Nelle versioni future, altri tipi di navigazione, ad esempio dopo un collegamento, possono anche richiamare gestori di modifica della posizione.
Quando si verifica un spostamento avanzato, LocationChanged
i gestori eventi registrati con i runtime Interactive Server e WebAssembly vengono in genere richiamati. Esistono casi in cui i gestori di modifica della posizione potrebbero non intercettare una navigazione avanzata. Ad esempio, l'utente potrebbe passare a un'altra pagina prima che un runtime interattivo diventi disponibile. Pertanto, è importante che la logica dell'app non si basi sul richiamo di un gestore di modifica della posizione, poiché non esiste garanzia che venga eseguito.
Quando si chiama NavigateTo:
- Se
forceLoad
èfalse
, ovvero l'impostazione predefinita:- E la navigazione avanzata è disponibile nell'URL corrente, Blazorviene attivata la navigazione avanzata.
- In caso contrario, Blazor esegue un ricaricamento a pagina intera per l'URL richiesto.
- Se
forceLoad
ètrue
: Blazor esegue un ricaricamento a pagina intera per l'URL richiesto, indipendentemente dal fatto che lo spostamento avanzato sia disponibile o meno.
È possibile aggiornare la pagina corrente chiamando NavigationManager.Refresh(bool forceLoad = false)
, che esegue sempre una navigazione avanzata, se disponibile. Se la navigazione migliorata non è disponibile, Blazor esegue un ricaricamento a pagina intera.
Navigation.Refresh();
Passa true
al parametro forceLoad
per assicurarti che venga effettuato sempre un ricaricamento a pagina intera, anche se la navigazione potenziata è disponibile.
Navigation.Refresh(true);
La navigazione avanzata è abilitata per impostazione predefinita, ma può essere controllata gerarchicamente e per ogni collegamento usando l'attributo data-enhance-nav
HTML.
Gli esempi seguenti disabilitano la navigazione avanzata:
<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>
Se la destinazione è unBlazor endpoint diverso, lo spostamento avanzato non si applica e il JavaScript lato client riprova effettuando un caricamento completo della pagina. Questo assicura che non ci sia alcuna confusione nel framework riguardo alle pagine esterne che non dovrebbero essere integrate in una pagina esistente.
Per abilitare la gestione avanzata dei moduli, aggiungere il Enhance parametro ai EditForm moduli o all'attributo data-enhance
ai moduli HTML (<form>
):
<EditForm ... Enhance ...>
...
</EditForm>
<form ... data-enhance ...>
...
</form>
La gestione avanzata dei moduli non è gerarchica e non passa ai moduli figlio:
Non supportato: non è possibile impostare lo spostamento avanzato sull'elemento predecessore di un modulo per abilitare la navigazione avanzata per il modulo.
<div ... data-enhance ...>
<form ...>
<!-- NOT enhanced -->
</form>
</div>
I post di modulo avanzati funzionano solo con Blazor endpoint. La pubblicazione di un modulo avanzato a un endpoint non valido genera un errore.
Per disabilitare la navigazione avanzata:
- Per un EditForm, rimuovere il parametro Enhance dall'elemento del modulo (o impostarlo su
false
:Enhance="false"
). - Per un codice HTML
<form>
, rimuovere l'attributodata-enhance
dall'elemento form (o impostarlo sufalse
:data-enhance="false"
).
Se il contenuto aggiornato non fa parte del rendering del server, la navigazione migliorata e la gestione dei moduli possono annullare modifiche dinamiche al DOM. Per mantenere il contenuto di un elemento, usare l'attributo data-permanent
.
Nell'esempio seguente il contenuto dell'elemento <div>
viene aggiornato dinamicamente da uno script quando la pagina viene caricata:
<div data-permanent>
...
</div>
Una volta che Blazor è stato avviato sul client, è possibile usare l'evento enhancedload
per ascoltare gli aggiornamenti di pagina avanzati. Ciò consente di riapplicare le modifiche al DOM che potrebbero essere state annullate da un aggiornamento di pagina avanzato.
Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));
Per disabilitare l'esplorazione avanzata e la gestione dei form a livello globale, vedere
La navigazione avanzata con il rendering statico lato server (SSR statico) richiede particolare attenzione durante il caricamento di JavaScript. Per ulteriori informazioni, vedere ASP.NET Core Blazor JavaScript con il rendering statico lato server (SSR).
Produrre un URI relativo al prefisso URI di base
In base all'URI di base dell'app, ToBaseRelativePath converte un URI assoluto in un URI relativo al prefisso dell'URI di base.
Si consideri l'esempio seguente:
try
{
baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
...
}
Se l'URI di base dell'app è https://localhost:8000
, vengono ottenuti i risultati seguenti:
- Il passaggio di
https://localhost:8000/segment
ininputURI
restituisce unbaseRelativePath
disegment
. - Passare
https://localhost:8000/segment1/segment2
ininputURI
risulta in unbaseRelativePath
disegment1/segment2
.
Se l'URI di base dell'app non corrisponde all'URI di base di inputURI
, viene generata un'eccezione ArgumentException .
Il passaggio https://localhost:8001/segment
inputURI
comporta l'eccezione seguente:
System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'
Stato della cronologia degli spostamenti
NavigationManager usa l'API Cronologia del browser per mantenere lo stato della cronologia di navigazione associato a ogni modifica della localizzazione apportata dall'applicazione. Mantenere lo stato della cronologia è particolarmente utile in scenari di reindirizzamento esterno, ad esempio quando si autentica gli utenti tramite provider di identità esterni. Per altre informazioni, vedere la sezione Opzioni di spostamento.
Opzioni di spostamento
Passare NavigationOptions a NavigateTo per controllare i comportamenti seguenti:
-
ForceLoad: ignorare il routing lato client e forzare il browser a caricare la nuova pagina dal server, indipendentemente dal fatto che l'URI sia gestito dal router lato client. Il valore predefinito è
false
. -
ReplaceHistoryEntry: Sostituisce la voce corrente nello stack di cronologia. Se
false
, aggiungere la nuova voce allo stack di cronologia. Il valore predefinito èfalse
. - HistoryEntryState: ottiene o imposta lo stato da aggiungere alla voce della cronologia.
Navigation.NavigateTo("/path", new NavigationOptions
{
HistoryEntryState = "Navigation state"
});
Per altre informazioni su come ottenere lo stato associato alla voce della cronologia di destinazione durante la gestione delle modifiche della posizione, vedere la sezione Gestire/impedire modifiche alla posizione.
Parametri di query
Usare l'attributo [SupplyParameterFromQuery]
per specificare che un parametro del componente proviene dalla stringa di query.
Utilizzare l'attributo
Nota
I parametri del componente possono ricevere i valori dei parametri della query solo nei componenti instradabili tramite la direttiva @page
.
Solo i componenti instradabili ricevono direttamente parametri di query per evitare di invertire il flusso di informazioni dall'alto verso il basso e rendere chiaro l'ordine di elaborazione dei parametri, sia dal framework che dall'app. Questa progettazione evita bug sottili nel codice dell'app scritto presupponendo un ordine di elaborazione dei parametri specifico. È possibile definire parametri a catena personalizzati o assegnare direttamente ai parametri dei componenti regolari per passare i valori dei parametri di query a componenti non instradabili.
I parametri del componente forniti dalla stringa di query supportano i tipi seguenti:
-
bool
,DateTime
,decimal
,double
,float
,Guid
,int
,long
,string
. - Varianti annullabili dei tipi precedenti.
- Matrici dei tipi precedenti, che siano nullable o meno nullable.
Viene applicata la corretta formattazione cultura-invariante per il tipo specificato (CultureInfo.InvariantCulture).
Specificare la proprietà Name dell'attributo [SupplyParameterFromQuery]
per usare un nome di parametro di query diverso dal nome del parametro del componente. Nell'esempio seguente il nome C# del parametro del componente è {COMPONENT PARAMETER NAME}
. È specificato un diverso nome di parametro di query per il segnaposto {QUERY PARAMETER NAME}
.
A differenza delle proprietà dei parametri del componente ([Parameter]
), [SupplyParameterFromQuery]
le proprietà possono essere contrassegnate private
oltre a public
.
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
private string? {COMPONENT PARAMETER NAME} { get; set; }
Proprio come le proprietà dei parametri dei componenti ([Parameter]
), le proprietà [SupplyParameterFromQuery]
sono sempre proprietà public
in .NET 6/7. In .NET 8 o versioni successive le [SupplyParameterFromQuery]
proprietà possono essere contrassegnate public
o private
.
[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }
Nell'esempio seguente con un URL di /search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman
:
- La
Filter
proprietà viene risolta inscifi stars
. - La
Page
proprietà viene risolta in3
. - La
Stars
matrice viene riempita dai parametri di query denominatistar
(Name = "star"
) e viene risolta inLeVar Burton
eGary Oldman
.
Nota
I parametri della stringa di query nel componente pagina instradabile seguente funzionano anche in un componente non instradabile senza una @page
direttiva, Search.razor
ad esempio per un componente condiviso Search
usato in altri componenti.
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; }
}
Usare GetUriWithQueryParameter per aggiungere, modificare o rimuovere uno o più parametri di query nell'URL corrente:
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})
Per l'esempio precedente:
- Il
{NAME}
segnaposto specifica il nome del parametro di query. Il{VALUE}
segnaposto specifica il valore come tipo supportato. I tipi supportati sono elencati più avanti in questa sezione. - Viene restituita una stringa uguale all'URL corrente con un singolo parametro:
- Aggiunto se il nome del parametro di query non esiste nell'URL corrente.
- Aggiornato al valore specificato se il parametro di query esiste nell'URL corrente.
- Rimosso se il tipo del valore specificato è nullable e il valore è
null
.
- La formattazione corretta cultura-invariata viene applicata per il tipo specificato (CultureInfo.InvariantCulture).
- Il nome e il valore del parametro di query sono codificati in URL.
- Tutti i valori con il nome del parametro di query corrispondente vengono sostituiti se sono presenti più istanze del tipo.
Chiamare GetUriWithQueryParameters per creare un URI costruito da Uri con più parametri aggiunti, aggiornati o rimossi. Per ogni valore, il framework usa value?.GetType()
per determinare il tipo di esecuzione per ogni parametro di query e seleziona la formattazione cultura-invariante corretta. Il framework genera un errore per i tipi non supportati.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters({PARAMETERS})
Il {PARAMETERS}
segnaposto è un oggetto IReadOnlyDictionary<string, object>
.
Passare una stringa URI a GetUriWithQueryParameters per generare un nuovo URI da un URI fornito con più parametri aggiunti, aggiornati o rimossi. Per ogni valore, il framework usa value?.GetType()
per determinare il tipo di esecuzione per ogni parametro di query e seleziona la corretta formattazione invariante rispetto alla cultura. Il framework genera un errore per i tipi non supportati. I tipi supportati sono elencati più avanti in questa sezione.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
- Il
{URI}
segnaposto è l'URI con o senza una stringa di query. - Il
{PARAMETERS}
segnaposto è unIReadOnlyDictionary<string, object>
.
I tipi supportati sono identici ai tipi supportati per i vincoli di route:
bool
DateTime
decimal
double
float
Guid
int
long
string
I tipi supportati includono:
- Varianti nullable dei tipi precedenti.
- Matrici dei tipi precedenti, che siano annullabili o meno.
Avviso
Con la compressione, abilitata per impostazione predefinita, evitare di creare componenti interattivi (autenticati/autorizzati) che visualizzano dati da fonti non attendibili. Le origini non attendibili includono parametri di route, stringhe di query, dati di JS interoperabilità e qualsiasi altra origine di dati che un utente di terze parti può controllare (database, servizi esterni). Per ulteriori informazioni, consultare le linee guida su ASP.NET Core e le linee guida per la mitigazione delle minacce durante il rendering interattivo lato server di ASP.NET Core.
Sostituire un valore del parametro di query quando il parametro esiste
Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
URL corrente | URL generato |
---|---|
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 |
Aggiungere un parametro di query e un valore quando il parametro non esiste
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
URL corrente | URL generato |
---|---|
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 |
Rimuovere un parametro di query quando il valore del parametro è null
Navigation.GetUriWithQueryParameter("full name", (string)null)
URL corrente | URL generato |
---|---|
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/ |
Aggiungere, aggiornare e rimuovere parametri di query
Nell'esempio seguente :
-
name
viene rimosso, se presente. -
age
viene aggiunto con un valore di25
(int
), se non presente. Se presente,age
viene aggiornato a un valore di25
. -
eye color
viene aggiunto o aggiornato a un valore digreen
.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["name"] = null,
["age"] = (int?)25,
["eye color"] = "green"
})
URL corrente | URL generato |
---|---|
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 |
Supporto per i valori enumerabili
Nell'esempio seguente :
-
full name
viene aggiunto o aggiornato aMorena Baccarin
, un singolo valore. -
ping
i parametri vengono aggiunti o sostituiti con35
,16
87
e240
.
Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["full name"] = "Morena Baccarin",
["ping"] = new int?[] { 35, 16, null, 87, 240 }
})
URL corrente | URL generato |
---|---|
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 |
Navigare con un parametro di query aggiunto o modificato
Per spostarsi con una stringa di query aggiunta o modificata, passare un URL generato a NavigateTo.
L'esempio seguente chiama:
-
GetUriWithQueryParameter per aggiungere o sostituire il
name
parametro di query usando un valore diMorena Baccarin
. - Chiamate NavigateTo per attivare la navigazione al nuovo URL.
Navigation.NavigateTo(
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));
La stringa di query di una richiesta viene ottenuta dalla NavigationManager.Uri proprietà :
@inject NavigationManager Navigation
...
var query = new Uri(Navigation.Uri).Query;
Per analizzare i parametri di una stringa di query, un approccio consiste nell'usare URLSearchParams
con l'interoperabilità di JavaScript (JS).
export createQueryString = (string queryString) => new URLSearchParams(queryString);
Per altre informazioni sull'isolamento JavaScript con i moduli JavaScript, vedere Chiamare le funzioni JavaScript dai metodi .NET in ASP.NET Core Blazor.
Routing tramite hash verso elementi denominati
Passare a un elemento nominato usando i seguenti approcci con un riferimento hash (#
) all'elemento. I percorsi agli elementi all'interno del componente e quelli per gli elementi nei componenti esterni utilizzano percorsi relativi alla radice. Una barra iniziale (/
) è facoltativa.
Esempi per ciascuno degli approcci seguenti illustrano la navigazione a un elemento con un id
di targetElement
nella componente Counter
.
Elemento di ancoraggio (
<a>
): conhref
<a href="/counter#targetElement">
NavLinkcomponente con :
href
<NavLink href="/counter#targetElement">
NavigationManager.NavigateTo passare l'URL relativo:
Navigation.NavigateTo("/counter#targetElement");
Nell'esempio seguente viene dimostrato il routing con hash verso intestazioni H2 con nomi all'interno di un componente e verso componenti esterni.
Home
Nei componenti (Home.razor
) e Counter
(Counter.razor
) posizionare il markup seguente nella parte inferiore del markup del componente esistente da utilizzare come destinazioni di navigazione. Il <div>
crea spazio verticale artificiale per illustrare il comportamento di scorrimento del browser.
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
Aggiungere il componente seguente HashedRouting
all'app.
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");
}
}
Interazione dell'utente con <Navigating>
il contenuto
Se si verifica un ritardo significativo durante la navigazione, ad esempio durante il caricamento differito di assembly in un'app Blazor WebAssembly o per una connessione di rete lenta a un'app lato server Blazor, il Router componente può indicare all'utente che si sta verificando una transizione di pagina.
Nella parte superiore del componente che specifica il Router componente, aggiungere una direttiva @using
per lo spazio dei nomi Microsoft.AspNetCore.Components.Routing.
@using Microsoft.AspNetCore.Components.Routing
Specificare il contenuto del Navigating parametro da visualizzare durante gli eventi di transizione della pagina.
Nel contenuto dell'elemento router (<Router>...</Router>
):
<Navigating>
<p>Loading the requested page…</p>
</Navigating>
Per un esempio che usa la Navigating proprietà , vedere Lazy load assemblies in ASP.NET Core Blazor WebAssembly.
Gestire gli eventi di spostamento asincroni con OnNavigateAsync
Il Router componente supporta una OnNavigateAsync funzionalità. Il OnNavigateAsync gestore viene richiamato quando l'utente:
- Visita l'itinerario per la prima volta accedendovi direttamente nel browser.
- Passa a un nuovo percorso usando un collegamento o un'invocazione 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)
{
...
}
}
Per un esempio che usa OnNavigateAsync, vedere Assemblies con caricamento pigro in ASP.NET Core Blazor WebAssembly.
Quando si esegue la pre-esecuzione sul server, OnNavigateAsync viene eseguito due volte:
- Una volta quando il componente endpoint richiesto viene inizialmente renderizzato in modo statico.
- Seconda volta che il browser esegue il rendering del componente endpoint.
Per impedire l'esecuzione del codice OnNavigateAsync dello sviluppatore due volte, il componente Routes
può archiviare il NavigationContext per usarlo nel metodo di ciclo di vita OnAfterRender{Async}
, dove firstRender
può essere controllato. Per ulteriori informazioni, vedere Pre-rendering con interoperabilità JavaScript.
Per impedire l'esecuzione del codice OnNavigateAsync dello sviluppatore due volte, il App
componente può archiviare per l'uso NavigationContext in OnAfterRender{Async}
, dove firstRender
può essere controllato. Per ulteriori informazioni, vedere Prerendering con interoperabilità JavaScript.
Gestire gli annullamenti in OnNavigateAsync
L'oggetto NavigationContext passato al OnNavigateAsync callback contiene un CancellationToken oggetto impostato quando si verifica un nuovo evento di navigazione. Il OnNavigateAsync callback deve generare quando questo token di annullamento è impostato per evitare di continuare a eseguire il OnNavigateAsync callback in una navigazione obsoleta.
Se un utente passa a un endpoint ma passa immediatamente a un nuovo endpoint, l'app non deve continuare a eseguire il OnNavigateAsync callback per il primo endpoint.
Nell'esempio seguente :
- Il token di annullamento viene passato alla chiamata a
PostAsJsonAsync
, che può annullare l'operazione POST se l'utente si allontana dall'endpoint/about
. - Il token di annullamento viene impostato durante un'operazione di prelettura del prodotto se l'utente si allontana dall'endpoint
/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);
}
}
}
}
Nota
Se il token di annullamento in NavigationContext viene annullato e non viene lanciata un'eccezione, si può verificare un comportamento indesiderato, come il rendering di un componente da una navigazione precedente.
Gestire/impedire modifiche alla posizione
RegisterLocationChangingHandler registra un gestore per elaborare gli eventi di navigazione in ingresso. Il contesto del gestore fornito da LocationChangingContext include le proprietà seguenti:
- TargetLocation: ottiene la posizione di destinazione.
- HistoryEntryState: ottiene lo stato associato alla voce della cronologia di destinazione.
- IsNavigationIntercepted: verifica se la navigazione è stata intercettata da un collegamento.
- CancellationToken: ottiene un CancellationToken per determinare se la navigazione è stata annullata, ad esempio per determinare se l'utente ha attivato una navigazione diversa.
- PreventNavigation: Chiamato per impedire che la navigazione continui.
Un componente può registrare più gestori di cambiamento della posizione nel metodo ciclo di vita
- Quando si selezionano collegamenti interni, ovvero collegamenti che puntano agli URL nel percorso di base dell'app.
- Durante lo spostamento tramite i pulsanti avanti e indietro in un browser.
I gestori vengono eseguiti solo per lo spostamento interno all'interno dell'app. Se l'utente seleziona un collegamento che passa a un sito diverso o modifica manualmente la barra degli indirizzi in un altro sito, i gestori di modifica della posizione non vengono eseguiti.
Implementare IDisposable ed eliminare i gestori registrati per annullarne la registrazione. Per altre informazioni, vedere Ciclo di vita dei componenti di ASP.NET Core Razor.
Importante
Non tentare di eseguire attività di pulizia DOM tramite JavaScript interop (JS) durante la gestione dei cambiamenti di posizione. Utilizzare il modello MutationObserver
nel JS client. Per ulteriori informazioni, vedere ASP.NET Core Blazor interoperabilità di JavaScript (JS interop).
Nell'esempio seguente viene registrato un gestore del cambio di posizione per eventi di navigazione.
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();
}
Poiché la navigazione interna può essere annullata in modo asincrono, possono verificarsi più chiamate sovrapposte ai gestori registrati. Ad esempio, più chiamate di gestori possono verificarsi quando l'utente seleziona rapidamente il pulsante Indietro in una pagina o seleziona più collegamenti prima dell'esecuzione di una navigazione. Di seguito è riportato un riepilogo della logica di spostamento asincrona:
- Se vengono registrati gestori del cambiamento di posizione, tutta la navigazione viene inizialmente annullata, quindi ripetuta se la navigazione non viene annullata.
- Se vengono effettuate richieste di spostamento sovrapposte, la richiesta più recente annulla sempre le richieste precedenti, il che significa quanto segue:
- L'app può trattare più selezioni di pulsanti indietro e avanti come una singola selezione.
- Se l'utente seleziona più collegamenti prima del completamento della navigazione, l'ultimo collegamento selezionato determina lo spostamento.
Per ulteriori informazioni su come passare NavigationOptions a NavigateTo per controllare le voci e lo stato dello stack della cronologia di navigazione, consultare la sezione Opzioni di navigazione.
Per ulteriori esempi di codice, vedere il NavigationManagerComponent
nel BasicTestApp
(dotnet/aspnetcore
origine di riferimento).
Nota
I link della documentazione all'origine di riferimento di .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per un rilascio specifico, usare il menu a tendina Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).
Il NavigationLock
componente intercetta gli eventi di navigazione purché venga eseguito il rendering, "bloccando" qualsiasi navigazione specificata fino a quando non viene presa una decisione per procedere o annullare. Usare NavigationLock
quando è possibile definire l'ambito dell'intercettazione di navigazione per la durata di un componente.
Parametri NavigationLock:
-
ConfirmExternalNavigation imposta una finestra di dialogo del browser per richiedere all'utente di confermare o annullare la navigazione esterna. Il valore predefinito è
false
. La visualizzazione della finestra di dialogo di conferma richiede l'interazione iniziale dell'utente con la pagina prima di attivare lo spostamento esterno con l'URL nella barra degli indirizzi del browser. Per altre informazioni sul requisito di interazione, vedere Window:beforeunload
event (documentazione MDN). - OnBeforeInternalNavigation definisce un callback per gli eventi di navigazione interna.
Nel componente NavLock
seguente:
- Un tentativo di seguire il collegamento al sito Web di Microsoft deve essere confermato dall'utente prima che la navigazione
https://www.microsoft.com
abbia esito positivo. viene chiamato per impedire l'esecuzione della navigazione se l'utente rifiuta di confermare la navigazione tramite una chiamata di interoperabilità JavaScript ( ) che genera la finestra di dialogo .
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();
}
}
}
Per ulteriori esempi di codice, vedere il componente ConfigurableNavigationLock
nel BasicTestApp
(dotnet/aspnetcore
fonte di riferimento).
Componente NavLink
Usare un componente NavLink al posto degli elementi del collegamento ipertestuale HTML (<a>
) quando si creano collegamenti di navigazione. Un NavLink componente si comporta come un <a>
elemento, tranne che attiva o disattiva una active
classe CSS in base a se href
corrisponde all'URL corrente. La active
classe aiuta un utente a capire quale pagina è la pagina attiva tra i collegamenti di spostamento visualizzati. Facoltativamente, assegnare a NavLink.ActiveClass un nome di classe CSS per applicare una classe CSS personalizzata al collegamento reso quando la route corrente corrisponde a href
.
Sono disponibili due NavLinkMatch opzioni che è possibile assegnare all'attributo Match
dell'elemento <NavLink>
:
-
NavLinkMatch.All: il NavLink è attivo quando corrisponde all'URL corrente, ignorando la stringa di query e il frammento. Per includere la corrispondenza nella stringa di query o nel frammento, usare l'opzione
Microsoft.AspNetCore.Components.Routing.NavLink.DisableMatchAllIgnoresLeftUriPart
AppContext
. - NavLinkMatch.Prefix (impostazione predefinita): l'oggetto NavLink è attivo quando corrisponde a qualsiasi prefisso dell'URL corrente.
Sono disponibili due NavLinkMatch opzioni che è possibile assegnare all'attributo Match
dell'elemento <NavLink>
:
- NavLinkMatch.All: il NavLink è attivo quando corrisponde all'intero URL corrente, inclusa la stringa di query e il frammento.
- NavLinkMatch.Prefix (impostazione predefinita): l'oggetto NavLink è attivo quando corrisponde a qualsiasi prefisso dell'URL corrente.
Nell'esempio precedente, il HomeNavLinkhref=""
corrisponde all'URL principale e riceve solo la classe CSS active
nel percorso di base predefinito dell'app (/
). Il secondo NavLink riceve la active
classe quando l'utente visita qualsiasi URL con un component
prefisso , /component
ad esempio e /component/another-segment
.
Per adottare la logica di corrispondenza personalizzata, la sottoclasse NavLink ed eseguire l'override del relativo metodo ShouldMatch
. Restituire true
dal metodo quando si desidera applicare la classe CSS active
:
public class CustomNavLink : NavLink
{
protected override bool ShouldMatch(string currentUriAbsolute)
{
// Custom matching logic
}
}
Gli attributi aggiuntivi NavLink dei componenti vengono passati al tag di ancoraggio renderizzato. Nell'esempio seguente il NavLink componente include l'attributo target
:
<NavLink href="example-page" target="_blank">Example page</NavLink>
Viene eseguito il rendering del markup HTML seguente:
<a href="example-page" target="_blank">Example page</a>
Avviso
A causa del modo in cui Blazor esegue il rendering del contenuto figlio, il rendering NavLink
dei componenti all'interno di un for
ciclo richiede una variabile di indice locale se la variabile del ciclo di incremento viene usata nel contenuto del NavLink
componente (figlio):
@for (int c = 1; c < 4; c++)
{
var ct = c;
<li ...>
<NavLink ...>
<span ...></span> Product #@ct
</NavLink>
</li>
}
L'uso di una variabile di indice in questo scenario è un requisito per qualsiasi componente figlio che utilizza una variabile di ciclo nel suo contenuto figlio, non solo per il componente NavLink
.
In alternativa, usare un foreach
ciclo con Enumerable.Range:
@foreach (var c in Enumerable.Range(1, 3))
{
<li ...>
<NavLink ...>
<span ...></span> Product #@c
</NavLink>
</li>
}
NavLink Le voci dei componenti possono essere create dinamicamente dai componenti dell'app tramite reflection. Nell'esempio seguente viene illustrato l'approccio generale per un'ulteriore personalizzazione.
Per la dimostrazione seguente viene usata una convenzione di denominazione standard coerente per i componenti dell'app:
- I nomi dei file dei componenti instradabili usano la notazione Pascal, ad esempio
Pages/ProductDetail.razor
. - I percorsi dei file dei componenti instradabili corrispondono ai rispettivi URL nel caso kebab++ con trattini visualizzati tra le parole nel modello di route di un componente. Ad esempio, un componente
ProductDetail
con un modello di route/product-detail
(@page "/product-detail"
) viene richiesto in un browser nell'URL relativo/product-detail
.
†Il Pascal case (Camel case maiuscolo) è una convenzione di scrittura senza spazi e punteggiatura, in cui la prima lettera di ogni parola è maiuscola, inclusa la prima parola.
*Kebab case è una convenzione di denominazione senza spazi e punteggiatura che usa lettere minuscole e trattini tra le parole.
Razor Nel markup del NavMenu
componente (NavMenu.razor
) nella pagina predefinitaHome
, NavLink i componenti vengono aggiunti da una raccolta:
<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>
Nel blocco @code
, il metodo GetRoutableComponents
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);
L'esempio precedente non include le pagine seguenti nell'elenco di componenti di cui è stato eseguito il rendering:
-
Home
page: la pagina viene elencata separatamente dai collegamenti generati automaticamente perché dovrebbe essere visualizzata nella parte superiore dell'elenco e impostare ilMatch
parametro . -
Error
page: la pagina di errore viene visualizzata solo dal framework e non deve essere elencata.
Per un esempio del codice precedente in un'app di esempio che è possibile eseguire localmente, ottieni l'app di esempio Blazor Web App o Blazor WebAssembly.
Integrazione del routing degli endpoint di ASP.NET Core
Questa sezione si applica a Blazor Web Apps che operano su un circuito.
Questa sezione si applica alle Blazor Server app.
Un Blazor Web App è integrato nell'Endpoint Routing di ASP.NET Core. Un'app ASP.NET Core è configurata per accettare connessioni in ingresso per i componenti interattivi con MapRazorComponents nel Program
file. Il componente radice predefinito (primo componente caricato) è il App
componente (App.razor
):
app.MapRazorComponents<App>();
Blazor Server è integrato nel Routing degli Endpoint di ASP.NET Core. Un'app ASP.NET Core è configurata per accettare connessioni in ingresso per i componenti interattivi con MapBlazorHub nel Program
file:
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
Blazor Server è integrato in ASP.NET routing dell'endpoint principale. Un'app core ASP.NET è configurata per accettare connessioni in ingresso per i componenti interattivi con MapBlazorHub in Startup.Configure
.
La configurazione tipica consiste nell'instradare tutte le richieste a una Razor pagina, che funge da host per la parte lato server dell'app Blazor Server . Per convenzione, la pagina host viene in genere denominata _Host.cshtml
nella Pages
cartella dell'app.
La percorso specificato nel file host viene chiamato percorso di fallback perché opera con una priorità bassa nella corrispondenza dei percorsi. La rotta di fallback viene utilizzata quando gli altri percorsi non corrispondono. In questo modo l'app può usare altri controller e pagine senza interferire con il routing dei componenti nell'app Blazor Server .
Per informazioni sulla configurazione MapFallbackToPage per l'hosting di server con URL non principale, consultare Ospitare e distribuire ASP.NET Core Blazor.