ASP.NET routing e navigazione core Blazor
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 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 8 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 (Router
componente , <Router>
in Routes.razor
) esegue il routing statico ai componenti durante il Blazor rendering statico lato server (SSR statico). Questo tipo di routing è denominato routing statico.
Quando al componente viene assegnata Routes
una modalità di rendering interattiva, il router diventa interattivo dopo ssr Blazor statico con routing statico nel 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 la pre-gestione perché il nuovo contenuto della pagina non viene richiesto dal server con una normale richiesta di pagina. Per altre informazioni, vedere Prerender ASP.NET Componenti di baseRazor.
Modelli di route
Il Router componente consente il routing ai Razor componenti e si trova nel componente dell'app Routes
(Components/Routes.razor
).
Il Router componente consente il routing ai Razor componenti. Il Router componente viene usato nel App
componente (App.razor
).
Quando viene compilato un Razor componente (.razor
) con una@page
direttiva, 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 RouteView componente:
- Riceve l'oggetto RouteData Router da 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 delBlazor framework 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.
non Router interagisce con i valori della stringa di query. Per usare le stringhe di query, vedere la sezione Stringhe di query.
In alternativa a specificare il modello di route come valore letterale stringa con la @page
direttiva , è possibile specificare modelli di route costanti con la @attribute
direttiva .
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 FocusOnNavigate componente imposta lo stato attivo dell'interfaccia utente su un elemento basato su un selettore CSS dopo lo spostamento da una pagina a un'altra.
<FocusOnNavigate RouteData="routeData" Selector="h1" />
Quando il Router componente passa a una nuova pagina, il FocusOnNavigate componente 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 ASP.NET Layout principaliBlazor.
Importante
Blazor Web Apps non usano il NotFound parametro (<NotFound>...</NotFound>
markup), ma il parametro è supportato per la compatibilità con le versioni precedenti per evitare una modifica di rilievo nel framework. La pipeline middleware core ASP.NET lato server elabora le richieste nel server. Usare tecniche lato server per gestire richieste non valide. Per altre informazioni, vedere ASP.NET Modalità di rendering coreBlazor.
Indirizzare ai componenti da più assembly
Questa sezione si applica a Blazor Web Apps.
Usare il Router parametro del AdditionalAssemblies componente e il generatore AddAdditionalAssemblies di convenzioni dell'endpoint per individuare i componenti instradabili in assembly aggiuntivi. Le sottosezioni seguenti illustrano quando e come usare ogni API.
Routing statico
Per individuare componenti instradabili da assembly aggiuntivi per il rendering statico lato server (SSR statico), anche se il router diventa in seguito interattivo per il rendering interattivo, gli assembly devono essere divulgati al Blazor framework. Chiamare il AddAdditionalAssemblies metodo con gli assembly aggiuntivi concatenati a MapRazorComponents nel file del progetto server Program
.
L'esempio seguente include i componenti instradabili nell'assembly BlazorSample.Client
del progetto usando il file del _Imports.razor
progetto:
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 ssri statici sono disponibili in ASP.NET librerie di classi core Razor (RCLs) 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 Routes
componente. Il Router
componente eredita il rendering interattivo lato server (SSR interattivo) dal Routes
componente. 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 altre informazioni, vedere Prerender ASP.NET Componenti di baseRazor.
Se il Routes
componente è definito nel progetto server, il AdditionalAssemblies parametro del Router
componente deve includere l'assembly .Client
del progetto. 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="new[] { 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 rendering Interattivo WebAssembly o 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 al 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 al User
componente 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 corrispondenti alle impostazioni cultura invarianti, vedere l'avviso sotto la tabella per altre informazioni.
Vincolo | Esempio | Esempi di corrispondenza | Invariante Impostazioni cultura corrispondenti |
---|---|---|---|
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, ad esempio int
o DateTime, usano sempre le impostazioni cultura inglese non dipendenti da paese/area geografica, presupponendo 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 di route
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 acquisito, che interrompe 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 di route predefinito lato server presuppone che se l'ultimo segmento di un URL di richiesta contiene un punto (.
) richiesto da 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 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 nel Program
file:
app.MapFallbackToFile("/example/{param?}", "index.html");
Per configurare un'app Blazor Server per instradare la richiesta con un punto nel param
parametro di route, aggiungere un modello di route di pagina di fallback con il parametro facoltativo nel Program
file:
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 per instradare la richiesta con un punto nel param
parametro di route, 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 catch-all
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 dello stato di URI e 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 anteporto 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 generato quando la posizione di spostamento è 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 query. |
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con una barra finale) che può essere anteporto 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 :
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 generato quando la posizione di spostamento è 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 query. |
Membro | Descrizione |
---|---|
Uri | Ottiene l'URI assoluto corrente. |
BaseUri | Ottiene l'URI di base (con una barra finale) che può essere anteporto 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 :
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 generato quando la posizione di spostamento è 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. |
GetUriWithQueryParameter | Restituisce un URI costruito aggiornando NavigationManager.Uri con un singolo parametro aggiunto, aggiornato o rimosso. Per altre 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 anteporto 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 spostamento è 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 informazioni seguenti sugli eventi di spostamento:
- Location: URL del nuovo percorso.
- IsNavigationIntercepted: se
true
, Blazor intercetta lo spostamento dal browser. Sefalse
, NavigationManager.NavigateTo ha causato l'esecuzione dello spostamento.
Componente seguente:
- Passa al componente dell'app
Counter
(Counter.razor
) quando il pulsante è selezionato usando NavigateTo. - Gestisce l'evento di modifica della posizione sottoscrivendo NavigationManager.LocationChanged.
Il
HandleLocationChanged
metodo viene scollegato quandoDispose
viene chiamato dal framework. Unhooking del metodo consente l'operazione di 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 altre informazioni sull'eliminazione dei componenti, vedere ASP.NET ciclo di vita dei componenti principaliRazor.
Spostamento avanzato 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 Blazor WebAssembly lo script (blazor.webassembly.js
). - La funzionalità non è disabilitata in modo esplicito.
- 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, perché non esiste alcuna garanzia dell'esecuzione del gestore.
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 lo spostamento avanzato non è disponibile, Blazor esegue un ricaricamento a pagina intera.
Navigation.Refresh();
Passare true
al forceLoad
parametro per assicurarsi che venga sempre eseguito un ricaricamento a pagina intera, anche se la navigazione avanzata è 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 da un endpoint, lo spostamento avanzato non si applica e il lato client JavaScript ritenta come caricamento completo della pagina. In questo modo non viene eseguita alcuna confusione con il framework relativo alle pagine esterne che non devono essere applicate patch 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 gli endpoint. La pubblicazione di un modulo avanzato in un endpoint diversoBlazor da un endpoint genera un errore.
Per disabilitare la navigazione avanzata:
- Per un EditFormoggetto , rimuovere il Enhance parametro dall'elemento del modulo (o impostarlo su
false
:Enhance="false"
). - Per un codice HTML
<form>
, rimuovere l'attributo dall'elementodata-enhance
form (o impostarlo sufalse
:data-enhance="false"
).
BlazorSe il contenuto aggiornato non fa parte del rendering del server, la navigazione avanzata e la mano del modulo 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>
Dopo Blazor l'avvio nel 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 moduli a livello globale, vedere ASP.NET avvio di CoreBlazor.
La navigazione avanzata con il rendering statico lato server (SSR statico) richiede particolare attenzione durante il caricamento di JavaScript. Per altre informazioni, vedere ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico).
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 restituisce
https://localhost:8000/segment
inputURI
unbaseRelativePath
oggetto disegment
. - Il passaggio di restituisce
https://localhost:8000/segment1/segment2
inputURI
unbaseRelativePath
oggetto 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 posizione apportata dall'app. Mantenere lo stato della cronologia è particolarmente utile in scenari di reindirizzamento esterni, ad esempio quando si autenticano gli utenti con provider esterniidentity. 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: sostituire 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.
Stringhe di query
Usare l'attributo [SupplyParameterFromQuery]
per specificare che un parametro del componente proviene dalla stringa di query.
Usare l'attributo con l'attributo [Parameter]
[SupplyParameterFromQuery]
per specificare che un parametro componente di un componente instradabile proviene dalla stringa di query.
Nota
I parametri del componente possono ricevere solo i valori dei parametri di query nei componenti instradabili con una @page
direttiva .
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
, ,double
float
,Guid
,int
,long
.string
decimal
- Varianti nullable dei tipi precedenti.
- Matrici dei tipi precedenti, che siano nullable o meno nullable.
La formattazione invariante delle impostazioni cultura corretta viene applicata per il tipo specificato (CultureInfo.InvariantCulture).
Specificare la [SupplyParameterFromQuery]
proprietà dell'attributo per usare un nome di parametro di Name query diverso dal nome del parametro del componente. Nell'esempio seguente il nome C# del parametro del componente è {COMPONENT PARAMETER NAME}
. Per il {QUERY PARAMETER NAME}
segnaposto viene specificato un nome di parametro di query diverso:
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]
), [SupplyParameterFromQuery]
le proprietà sono sempre public
proprietà 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 invariante delle impostazioni cultura corretta 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 runtime per ogni parametro di query e seleziona la formattazione invariante delle impostazioni cultura 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 runtime per ogni parametro di query e seleziona la formattazione invariante delle impostazioni cultura corretta. 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 è un oggettoIReadOnlyDictionary<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 nullable o meno nullable.
Avviso
Con la compressione, abilitata per impostazione predefinita, evitare di creare componenti interattivi interattivi (autenticati/autorizzati) che eseguono il rendering dei dati da origini 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 altre informazioni, vedere linee guida ASP.NET Core BlazorSignalR e Linee guida per la mitigazione delle minacce per ASP.NET rendering lato server interattivo CoreBlazor.
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 (25
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 |
Spostarsi con una stringa di query aggiunta o modificata
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à 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 con hash a elementi denominati
Passare a un elemento denominato usando gli approcci seguenti con un riferimento hash (#
) all'elemento . Le route agli elementi all'interno del componente e instradano gli elementi nei componenti esterni usano percorsi relativi alla radice. Una barra iniziale (/
) è facoltativa.
Esempi per ognuno degli approcci seguenti illustrano la navigazione a un elemento con un id
di targetElement
nel Counter
componente :
Elemento Anchor (
<a>
) con :href
<a href="/counter#targetElement">
NavLinkcomponente con :
href
<NavLink href="/counter#targetElement">
NavigationManager.NavigateTo passaggio dell'URL relativo:
Navigation.NavigateTo("/counter#targetElement");
Nell'esempio seguente viene illustrato il routing con hash a intestazioni H2 denominate all'interno di un componente e a componenti esterni.
Home
Nei componenti (Home.razor
) e Counter
(Counter.razor
) posizionare il markup seguente nella parte inferiore del markup del componente esistente da usare come destinazioni di spostamento. Crea <div>
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 lo spostamento, ad esempio durante il caricamento differita di assembly in un'app Blazor WebAssembly o per una connessione di rete lenta a un'app Blazor lato server, 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 @using
direttiva per lo spazio dei Microsoft.AspNetCore.Components.Routing nomi :
@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 un itinerario per la prima volta passando a esso direttamente nel browser.
- Passa a una nuova route usando un collegamento o una NavigationManager.NavigateTo chiamata.
<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 , vedere Assembly di caricamento differita OnNavigateAsyncin ASP.NET Core Blazor WebAssembly.
Quando si esegue la pre-esecuzione sul server, OnNavigateAsync viene eseguito due volte:
- Quando il componente endpoint richiesto viene inizialmente sottoposto a rendering statico.
- Seconda volta che il browser esegue il rendering del componente endpoint.
Per impedire l'esecuzione del codice OnNavigateAsync dello sviluppatore due volte, il Routes
componente può archiviare per l'uso NavigationContext nel metodo del OnAfterRender{Async}
ciclo di vita, dove firstRender
può essere controllato. Per altre informazioni, vedere Prerendering with JavaScript interop (Prerendering with JavaScript interop).
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 altre informazioni, vedere Prerendering with JavaScript interop (Prerendering with JavaScript interop).
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, non viene generato un errore imprevisto, ad esempio il rendering di un componente da una struttura di spostamento precedente.
Gestire/impedire modifiche alla posizione
RegisterLocationChangingHandler registra un gestore per elaborare gli eventi di spostamento 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: ottiene un valore che indica se lo spostamento è stato intercettato da un collegamento.
- CancellationToken: ottiene un CancellationToken oggetto 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 modifica della posizione nel metodo del OnAfterRender{Async}
ciclo di vita. La navigazione richiama tutti i gestori di modifica della posizione registrati nell'intera app (tra più componenti) e qualsiasi spostamento interno li esegue tutti in parallelo. Oltre ai NavigateTo gestori vengono richiamati:
- 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 interoperabilità JavaScript (JS) durante la gestione delle modifiche della posizione. Usare il MutationObserver
modello in JS nel client. Per altre informazioni, vedere ASP.NET Core JavaScript interoperabilità (interoperabilità).For more information, see ASP.NET Core Blazor JavaScript interoperability (JS interop).
Nell'esempio seguente viene registrato un gestore di modifica della posizione per gli eventi di spostamento.
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é lo spostamento interno può essere annullato 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 di modifica della posizione, tutto lo spostamento viene inizialmente ripristinato, quindi riprodotto se lo spostamento non viene annullato.
- 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 altre informazioni sul passaggio NavigationOptions a NavigateTo per controllare le voci e lo stato dello stack della cronologia di navigazione, vedere la sezione Opzioni di spostamento.
Per altri esempi di codice, vedere in ( origine di riferimento).For additional example code, see the NavigationManagerComponent
in the BasicTestApp
(dotnet/aspnetcore
reference source).
Nota
I collegamenti della documentazione all'origine del riferimento .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 una versione specifica, usare l'elenco a discesa 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 imposta un callback per gli eventi di spostamento interni.
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. - PreventNavigationviene chiamato per impedire l'esecuzione della navigazione se l'utente rifiuta di confermare la navigazione tramite una chiamata di interoperabilità JavaScript (JS) che genera laJS
confirm
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 altri esempi di codice, vedere il componente nell'origine BasicTestApp
di riferimento (dotnet/aspnetcore
).ConfigurableNavigationLock
Componente NavLink
Usare un NavLink componente al posto degli elementi del collegamento ipertestuale HTML (<a>
) durante la creazione di collegamenti di spostamento. Un NavLink componente si comporta come un <a>
elemento, ad eccezione del fatto che attiva o disattiva una active
classe CSS in base al fatto href
che corrisponda all'URL corrente. La active
classe aiuta un utente a capire quale pagina è la pagina attiva tra i collegamenti di spostamento visualizzati. Facoltativamente, assegnare un nome di classe CSS a per NavLink.ActiveClass applicare una classe CSS personalizzata al collegamento sottoposto a rendering quando la route corrente corrisponde a href
.
Sono disponibili due NavLinkMatch opzioni che è possibile assegnare all'attributo Match
dell'elemento <NavLink>
:
- NavLinkMatch.AllNavLink: è attivo quando corrisponde all'intero URL corrente.
- NavLinkMatch.Prefix (impostazione predefinita): l'oggetto NavLink è attivo quando corrisponde a qualsiasi prefisso dell'URL corrente.
Nell'esempio precedente, corrisponde HomeNavLink href=""
all'URL home e riceve solo la active
classe CSS 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
.
Gli attributi aggiuntivi NavLink dei componenti vengono passati al tag di ancoraggio sottoposto a rendering. 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 usa una variabile di ciclo nel contenuto figlio, non solo per il NavLink
componente.
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 distinzione tra maiuscole e minuscole 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
.
†La notazione Pascal (lettere maiuscole) è una convenzione di denominazione senza spazi e punteggiatura e con la prima lettera di ogni parola in maiuscolo, 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>
Metodo GetRoutableComponents
nel @code
blocco:
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 in locale, ottenere l'app Blazor Web Appdi esempio o Blazor WebAssembly .
integrazione del routing degli endpoint core ASP.NET
Questa sezione si applica a Blazor Web Apps che opera su un circuito.
Questa sezione si applica alle Blazor Server app.
Un Blazor Web App oggetto è integrato in ASP.NET routing dell'endpoint principale. 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 in ASP.NET routing dell'endpoint principale. 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 route specificata nel file host viene chiamata route di fallback perché opera con una priorità bassa nella corrispondenza delle route. La route di fallback viene usata quando altre route 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 URL non radice, vedere Ospitare e distribuire ASP.NET Core Blazor.