Evento
Campionato do Mundo de Power BI DataViz
Feb 14, 4 PM - Mar 31, 4 PM
Con 4 posibilidades de entrar, poderías gañar un paquete de conferencias e facelo ao Live Grand Finale en Las Vegas
Máis informaciónEste explorador xa non é compatible.
Actualice a Microsoft Edge para dispoñer das funcionalidades máis recentes, as actualizacións de seguranza e a asistencia técnica.
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Aviso
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la directiva de compatibilidad de .NET y .NET Core. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión de .NET 9 de este artículo.
En este artículo se explica cómo administrar el enrutamiento de solicitudes de la aplicación Blazor y a usar el componente NavLink para crear vínculos de navegación.
Importante
En los ejemplos de código de este artículo se muestran los métodos llamados en Navigation
, que es un NavigationManager insertado en clases y componentes.
Esta sección es aplicable a Blazor Web App.
Si la representación previa está habilitada, el router Blazor (componente Router
, <Router>
en Routes.razor
) realiza el enrutamiento estático a los componentes durante la representación estática del lado del servidor (SSR estático). Este tipo de enrutamiento se denomina enrutamiento estático.
Cuando se asigna un modo de representación interactivo al componente Routes
, el enrutador Blazor se vuelve interactivo después de SSR estático con enrutamiento estático en el servidor. Este tipo de enrutamiento se denomina enrutamiento interactivo.
Los enrutadores estáticos usan el enrutamiento de puntos de conexión y la ruta de acceso de la solicitud HTTP para determinar qué componente se va a representar. Cuando el enrutador se vuelve interactivo, usa la dirección URL del documento (la dirección URL de la barra de direcciones del explorador) para determinar qué componente se va a representar. Esto significa que el enrutador interactivo puede cambiar dinámicamente qué componente se representa si la dirección URL del documento cambia dinámicamente a otra dirección URL interna válida y puede hacerlo sin realizar una solicitud HTTP para capturar nuevo contenido de página.
El enrutamiento interactivo también impide la representación previa porque no se solicita contenido de página nueva desde el servidor con una solicitud de página normal. Para obtener más información, consulta Representación previa de componentes Razor de ASP.NET Core .
El componente Router permite el enrutamiento a los componentes Razor y se encuentra en el componente Routes
de la aplicación (Components/Routes.razor
).
El componente Router habilita el enrutamiento a los componentes Razor. El componente Router se usa en el componente App
(App.razor
).
Cuando se compila un componente Razor (.razor
) con una directiva @page
, la clase de componente generada recibe un elemento RouteAttribute que especifica la plantilla de ruta del componente.
Cuando se inicia la aplicación, el ensamblado especificado como AppAssembly
del enrutador se examina para recopilar información de ruta de los componentes de la aplicación que tienen un elemento RouteAttribute.
En tiempo de ejecución, el componente RouteView:
Opcionalmente, se puede especificar un parámetro DefaultLayout con una clase de diseño para los componentes que no tengan especificado un diseño con la directiva @layout
. Las plantillas de proyecto de Blazor del marco especifican el componente MainLayout
(MainLayout.razor
) como diseño predeterminado de la aplicación. Para obtener más información sobre los diseños, consulta Diseños de Blazor en ASP.NET Core.
Los componentes admiten varias plantillas de ruta mediante varias directivas @page
. El componente de ejemplo siguiente se carga en las solicitudes de /blazor-route
y /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
Para que las direcciones URL se resuelvan correctamente, la aplicación debe incluir una etiqueta <base>
(ubicación del contenido de <head>
) con la ruta de acceso base de la aplicación especificada en el atributo href
. Para obtener más información, consulta Hospedaje e implementación de ASP.NET Core Blazor.
Router no interactúa con los valores de cadena de consulta. Para trabajar con cadenas de consulta, consulta la sección Cadena de consulta.
Como alternativa a especificar la plantilla de ruta como literal de cadena con la directiva @page
, se pueden especificar plantillas de ruta basadas en constantes con la directiva @attribute
.
En el ejemplo siguiente, la directiva @page
de un componente se reemplaza por la directiva @attribute
y la plantilla de ruta basada en constantes en Constants.CounterRoute
, que se establece en otra parte de la aplicación en "/counter
”:
- @page "/counter"
+ @attribute [Route(Constants.CounterRoute)]
Nota
Con la publicación de ASP.NET Core 5.0.1 y para las versiones 5.x adicionales, el componente Router
incluye el parámetro PreferExactMatches
establecido en @true
. Para más información, vea Migración de ASP.NET Core 3.1 a 5.0.
El componente FocusOnNavigate establece el foco de la interfaz de usuario en un elemento basado en un selector CSS después de navegar de una página a otra.
<FocusOnNavigate RouteData="routeData" Selector="h1" />
Cuando el componente Router navega a una página nueva, el componente FocusOnNavigate establece el foco en el encabezado de nivel superior de la página (<h1>
). Se trata de una estrategia común para asegurarse de que se anuncia una navegación de página cuando se usa un lector de pantalla.
El componente Router permite a la aplicación especificar contenido personalizado si no se encuentra contenido para la ruta solicitada.
Establezca contenido personalizado para el parámetro Router del componente NotFound:
<Router ...>
...
<NotFound>
...
</NotFound>
</Router>
Los elementos arbitrarios se admiten como contenido de los parámetros NotFound, como otros componentes interactivos. Para aplicar un diseño predeterminado al contenido de NotFound, vea Diseños de Blazor en ASP.NET Core.
Importante
Blazor Web App no utiliza el parámetro NotFound (marcado <NotFound>...</NotFound>
), pero el parámetro se admite para mantener la compatibilidad con versiones anteriores y evitar un cambio importante en el framework. La canalización de middleware del lado servidor ASP.NET procesa las solicitudes en el servidor. Usa técnicas del lado servidor para controlar las solicitudes incorrectas.
†Compatible en este contexto, significa que al colocar el marcado <NotFound>...</NotFound>
no da lugar a una excepción, pero usando el marcaje tampoco es efectivo.
Para obtener más información, incluido un enfoque recomendado para controlar solicitudes incorrectas, consulte ASP.NET Core Blazor modos de representación.
Esta sección es aplicable a Blazor Web App.
Use el parámetro Router del componente AdditionalAssemblies y el constructor de convenciones de punto de conexión AddAdditionalAssemblies para descubrir componentes enrutables en ensamblados adicionales. Las siguientes subsecciones explican cuándo y cómo usar cada API.
Para detectar componentes enrutables de ensamblados adicionales para la representación estática del lado servidor (SSR estático), incluso si el enrutador se convierte más adelante en interactivo para la representación interactiva, los ensamblados deben revelarse al marco Blazor. Llame al método AddAdditionalAssemblies con los ensamblados adicionales encadenados a MapRazorComponents en el archivo Program
del proyecto del servidor.
El siguiente ejemplo incluye los componentes enrutables en el ensamblado del proyecto de BlazorSample.Client
usando el archivo _Imports.razor
del proyecto:
app.MapRazorComponents<App>()
.AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
Nota
La guía anterior también se aplica en escenarios de biblioteca de clases de componentes. Encontrará orientación adicional importante para las bibliotecas de clases y SSR estático en Bibliotecas de clases de ASP.NET Core Razor (RCL) con representación estática del lado del servidor (SSR estático).
Se puede asignar un modo de enrutador interactivo al componente de Routes
(Routes.razor
) que hace que el enrutador de Blazor se vuelva interactivo tras el SSR estático y el enrutamiento estático en el servidor. Por ejemplo, <Routes @rendermode="InteractiveServer" />
asigna la representación interactiva del lado servidor (SSR interactiva) al componente Routes
. El componente Router
hereda la representación interactiva del lado del servidor (SSR interactiva) del componente Routes
. El enrutador se vuelve interactivo después del enrutamiento estático en el servidor.
La navegación interna para el enrutamiento interactivo no implica solicitar contenido de página nuevo desde el servidor. Por lo tanto, la representación previa no se produce para las solicitudes de página internas. Para obtener más información, consulta Representación previa de componentes Razor de ASP.NET Core .
Si el componente Routes
está definido en el proyecto del servidor, el parámetro AdditionalAssemblies del componente Router
debería incluir el ensamblado del proyecto .Client
. Esto permite que el enrutador funcione correctamente cuando se representa de forma interactiva.
En el siguiente ejemplo, el componente Routes
se encuentra en el proyecto de servidor, y el archivo _Imports.razor
del proyecto BlazorSample.Client
indica el ensamblado para buscar componentes enrutables:
<Router
AppAssembly="..."
AdditionalAssemblies="[ typeof(BlazorSample.Client._Imports).Assembly ]">
...
</Router>
Se examinan los ensamblados adicionales, además del ensamblado especificado para AppAssembly.
Nota
La guía anterior también se aplica en escenarios de biblioteca de clases de componentes.
Como alternativa, los componentes enrutables solo existen en el proyecto .Client
con WebAssembly interactivo global o representación automática aplicada, y el componente Routes
se define en el proyecto .Client
, no en el proyecto servidor. En este caso, no hay ensamblados externos con componentes enrutables, por lo que no es necesario especificar un valor para AdditionalAssemblies.
Esta sección es aplicable a aplicaciones Blazor Server.
Use el parámetro Router del componente AdditionalAssemblies y el constructor de convenciones de punto de conexión AddAdditionalAssemblies para descubrir componentes enrutables en ensamblados adicionales.
En el siguiente ejemplo, Component1
es un componente enrutable definido en una biblioteca de clases de componentes llamada ComponentLibrary
:
<Router
AppAssembly="..."
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }">
...
</Router>
Se examinan los ensamblados adicionales, además del ensamblado especificado para AppAssembly.
El enrutador usa parámetros de ruta para rellenar los parámetros de componente correspondientes con el mismo nombre. Los nombres de parámetros de ruta no distinguen mayúsculas de minúsculas. En el ejemplo siguiente, el parámetro text
asigna el valor del segmento de ruta a la propiedad Text
del componente. Cuando se realiza una solicitud para /route-parameter-1/amazing
, el contenido se representa como 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; }
}
Se admiten parámetros opcionales. En el ejemplo siguiente, el parámetro opcional text
asigna el valor del segmento de ruta a la propiedad Text
del componente. Si el segmento no está presente, el valor de Text
se establece en fantastic
.
No se admiten parámetros opcionales. En el ejemplo siguiente, se aplican dos directivas @page
. La primera directiva permite navegar al componente sin un parámetro, mientras que la segunda directiva asigna el valor del parámetro de ruta {text}
a la propiedad Text
del 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";
}
}
Cuando se usa el método del ciclo de vida OnInitialized{Async}
en lugar del método del ciclo de vida OnParametersSet{Async}
, la asignación predeterminada de la propiedad Text
a fantastic
no se produce si el usuario navega dentro del mismo componente. Por ejemplo, esta situación surge cuando el usuario navega de /route-parameter-2/amazing
a /route-parameter-2
. A medida que la instancia del componente persiste y acepta nuevos parámetros, el método OnInitialized
no se invoca de nuevo.
Nota
Los parámetros de ruta no funcionan con los valores de cadena de consulta. Para trabajar con cadenas de consulta, consulta la sección Cadena de consulta.
Una restricción de ruta fuerza la coincidencia de tipos en un segmento de ruta a un componente.
En el siguiente ejemplo, la ruta al componente User
solo coincide en estos casos:
Id
en la dirección URL de la solicitud.Id
es un tipo de entero (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
Las restricciones de ruta no funcionan con los valores de cadena de consulta. Para trabajar con cadenas de consulta, consulta la sección Cadena de consulta.
En la siguiente tabla figuran las restricciones de ruta que hay disponibles. Para obtener más información sobre las restricciones de ruta que coinciden con la referencia cultural invariable, consulta la advertencia que aparece después de la tabla.
Restricción | Ejemplo | Coincidencias de ejemplo | Invariable referencia cultural coincidencia |
---|---|---|---|
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} |
No BlazorSample.styles.css , no favicon.ico |
Sí |
Aviso
Las restricciones de ruta que comprueban la dirección URL y que se convierten en un tipo CLR (como int
o DateTime) usan siempre la referencia cultural invariable. Estas restricciones dan por supuesto que la dirección URL no es localizable.
Las restricciones de ruta también funcionan con parámetros opcionales. En el ejemplo siguiente, Id
es obligatorio, pero Option
es un parámetro de ruta booleano opcional.
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; }
}
La siguiente plantilla de ruta captura accidentalmente las rutas de acceso de recursos estáticos en su parámetro de ruta opcional (Optional
). Por ejemplo, se captura la hoja de estilos de la aplicación (.styles.css
), que interrumpe los estilos de la aplicación:
@page "/{optional?}"
...
@code {
[Parameter]
public string? Optional { get; set; }
}
Para restringir un parámetro de ruta para capturar rutas de acceso que no son de archivo, usa la restricción :nonfile
en la plantilla de ruta:
@page "/{optional:nonfile?}"
Una plantilla de ruta predeterminada del lado servidor supone que si el último segmento de una dirección URL de solicitud contiene un punto (.
) es porque se solicita un archivo. Por ejemplo, el enrutador interpreta la dirección URL relativa /example/some.thing
como una solicitud de un archivo denominado some.thing
. Sin configuración adicional, una aplicación devuelve una respuesta 404: no encontrado si se pretendía enrutar some.thing
a un componente con una directiva @page
y some.thing
es un valor de parámetro de ruta. Para usar una ruta con uno o más parámetros que contengan un punto, la aplicación debe configurar la ruta con una plantilla personalizada.
Ten en cuenta el siguiente componente Example
que puede recibir un parámetro de ruta del último segmento de la dirección 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; }
}
Para permitir que la aplicación Server de una Blazor WebAssemblysolución hospedada enrute la solicitud con un punto en el parámetro de ruta param
, agrega una plantilla de ruta de archivo de reserva con el parámetro opcional en el archivo Program
:
app.MapFallbackToFile("/example/{param?}", "index.html");
Para configurar una aplicación Blazor Server para enrutar la solicitud con un punto en el parámetro de ruta param
, agrega una plantilla de ruta de página de reserva con el parámetro opcional en el archivo Program
:
app.MapFallbackToPage("/example/{param?}", "/_Host");
Para obtener más información, consulta Enrutamiento en ASP.NET Core.
Para permitir que la aplicación Server de una Blazor WebAssemblysolución hospedada enrute la solicitud con un punto en el parámetro de ruta param
, agrega una plantilla de ruta de archivo de reserva con el parámetro opcional en Startup.Configure
.
Startup.cs
:
endpoints.MapFallbackToFile("/example/{param?}", "index.html");
Para configurar una aplicación Blazor Server para enrutar la solicitud con un punto en el parámetro de ruta param
, agrega una plantilla de ruta de página de reserva con el parámetro opcional en Startup.Configure
.
Startup.cs
:
endpoints.MapFallbackToPage("/example/{param?}", "/_Host");
Para obtener más información, consulta Enrutamiento en ASP.NET Core.
Los parámetros de ruta de captura general, que capturan rutas de acceso en varios límites de carpeta, se admiten en los componentes.
Los parámetros de ruta de captura general son:
string
. El marco no proporciona conversión automática.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; }
}
Para la dirección URL /catch-all/this/is/a/test
con una plantilla de ruta de /catch-all/{*pageRoute}
, el valor de PageRoute
se establece en this/is/a/test
.
Las barras diagonales y los segmentos de la ruta de acceso capturada están descodificados. En el caso de una plantilla de ruta de /catch-all/{*pageRoute}
, la dirección URL /catch-all/this/is/a%2Ftest%2A
produce this/is/a/test*
.
Usa NavigationManager para administrar los URI y la navegación en el código de C#. NavigationManager proporciona el evento y los métodos que se muestran en la siguiente tabla.
Miembro | Descripción |
---|---|
Uri | Obtiene el URI absoluto actual. |
BaseUri | Obtiene el URI base (con una barra diagonal final) que se puede anteponer a las rutas de acceso de URI relativo para generar un URI absoluto. Normalmente, BaseUri corresponde al atributo href del elemento <base> del documento (ubicación del contenido de <head> ). |
NavigateTo | Navega al URI especificado. Si forceLoad es false :
forceLoad es true :
Para más información, consulte la sección Navegación mejorada y control de formularios. Si |
LocationChanged | Evento que se desencadena cuando la ubicación de navegación ha cambiado. Para obtener más información, vea la sección Cambios de ubicación. |
ToAbsoluteUri | Convierte un URI relativo en un URI absoluto. |
ToBaseRelativePath | En función del URI base de la aplicación, convierte un URI absoluto en un URI relativo al prefijo de URI base. Para obtener un ejemplo, consulte la sección Generar un URI relativo al prefijo de URI base. |
RegisterLocationChangingHandler |
Registra un controlador para procesar los eventos de navegación entrantes. La llamada a NavigateTo siempre invoca al controlador. |
GetUriWithQueryParameter | Devuelve un URI construido mediante la actualización de NavigationManager.Uri con un único parámetro agregado, actualizado o quitado. Para obtener más información, consulta la sección Cadenas consulta. |
Miembro | Descripción |
---|---|
Uri | Obtiene el URI absoluto actual. |
BaseUri | Obtiene el URI base (con una barra diagonal final) que se puede anteponer a las rutas de acceso de URI relativo para generar un URI absoluto. Normalmente, BaseUri corresponde al atributo href del elemento <base> del documento (ubicación del contenido de <head> ). |
NavigateTo | Navega al URI especificado. Si forceLoad es true :
replace es true , el URI actual en el historial del explorador se reemplaza en lugar de insertar un URI nuevo en la pila del historial. |
LocationChanged | Evento que se desencadena cuando la ubicación de navegación ha cambiado. Para obtener más información, vea la sección Cambios de ubicación. |
ToAbsoluteUri | Convierte un URI relativo en un URI absoluto. |
ToBaseRelativePath | En función del URI base de la aplicación, convierte un URI absoluto en un URI relativo al prefijo de URI base. Para obtener un ejemplo, consulte la sección Generar un URI relativo al prefijo de URI base. |
RegisterLocationChangingHandler |
Registra un controlador para procesar los eventos de navegación entrantes. La llamada a NavigateTo siempre invoca al controlador. |
GetUriWithQueryParameter | Devuelve un URI construido mediante la actualización de NavigationManager.Uri con un único parámetro agregado, actualizado o quitado. Para obtener más información, consulta la sección Cadenas consulta. |
Miembro | Descripción |
---|---|
Uri | Obtiene el URI absoluto actual. |
BaseUri | Obtiene el URI base (con una barra diagonal final) que se puede anteponer a las rutas de acceso de URI relativo para generar un URI absoluto. Normalmente, BaseUri corresponde al atributo href del elemento <base> del documento (ubicación del contenido de <head> ). |
NavigateTo | Navega al URI especificado. Si forceLoad es true :
replace es true , el URI actual en el historial del explorador se reemplaza en lugar de insertar un URI nuevo en la pila del historial. |
LocationChanged | Evento que se desencadena cuando la ubicación de navegación ha cambiado. Para obtener más información, vea la sección Cambios de ubicación. |
ToAbsoluteUri | Convierte un URI relativo en un URI absoluto. |
ToBaseRelativePath | En función del URI base de la aplicación, convierte un URI absoluto en un URI relativo al prefijo de URI base. Para obtener un ejemplo, consulte la sección Generar un URI relativo al prefijo de URI base. |
GetUriWithQueryParameter | Devuelve un URI construido mediante la actualización de NavigationManager.Uri con un único parámetro agregado, actualizado o quitado. Para obtener más información, consulta la sección Cadenas consulta. |
Miembro | Descripción |
---|---|
Uri | Obtiene el URI absoluto actual. |
BaseUri | Obtiene el URI base (con una barra diagonal final) que se puede anteponer a las rutas de acceso de URI relativo para generar un URI absoluto. Normalmente, BaseUri corresponde al atributo href del elemento <base> del documento (ubicación del contenido de <head> ). |
NavigateTo | Navega al URI especificado. Si forceLoad es true :
|
LocationChanged | Evento que se desencadena cuando la ubicación de navegación ha cambiado. |
ToAbsoluteUri | Convierte un URI relativo en un URI absoluto. |
ToBaseRelativePath | En función del URI base de la aplicación, convierte un URI absoluto en un URI relativo al prefijo de URI base. Para obtener un ejemplo, consulte la sección Generar un URI relativo al prefijo de URI base. |
En el caso del evento LocationChanged, LocationChangedEventArgs proporciona la información siguiente sobre los eventos de navegación:
true
, Blazor ha interceptado la navegación del explorador. Si false
, NavigationManager.NavigateTo hizo que se produjera la navegación.El siguiente componente:
Counter
de la aplicación (Counter.razor
) cuando se selecciona el botón con NavigateTo.El método HandleLocationChanged
se desenlaza cuando el marco llama a Dispose
. Al desenlazar el método se permite la recolección de elementos no utilizados del componente.
La implementación del registrador registra la siguiente información cuando se selecciona el botón:
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;
}
}
Para obtener más información sobre la eliminación de componentes, consulta Ciclo de vida de componentes Razor de ASP.NET Core.
Esta sección es aplicable a Blazor Web App.
Las Blazor Web App permiten dos tipos de enrutamiento para la navegación de páginas y las solicitudes de control de formularios:
fetch
en su lugar. Luego, Blazor aplica una revisión al contenido de respuesta en el DOM de la página. La navegación mejorada y el control de formularios de Blazor evitan la necesidad de que se recarguen las páginas completas y conserva más el estado de las páginas, por lo que las páginas se cargan más rápidamente y normalmente sin perder la posición de desplazamiento del usuario en la página.La navegación mejorada está disponible cuando:
blazor.web.js
), no el script de Blazor Server (blazor.server.js
) ni el script de Blazor WebAssembly (blazor.webassembly.js
).Si están habilitados el enrutamiento del lado servidor y la navegación mejorada están habilitados, los controladores de cambio de ubicación solo se invocan para la navegaciones mediante programación iniciada desde un entorno de ejecución interactivo. En futuras versiones, otros tipos de navegación, como seguir un vínculo, también podrán invocar controladores de cambio de ubicación.
Cuando se produce una navegación mejorada, normalmente se invocan los LocationChanged
controladores de eventos registrados con el servidor interactivo y los runtime de WebAssembly. Hay casos en los que es posible que los controladores de cambio de ubicación no intercepten una navegación mejorada. Por ejemplo, el usuario podría cambiar a otra página antes de que un entorno de ejecución interactivo esté disponible. Por lo tanto, es importante que la lógica de la aplicación no dependa de invocar un controlador de cambio de ubicación, ya que no hay ninguna garantía de que el controlador se ejecute.
Al llamar a NavigateTo:
forceLoad
es false
, que es el valor predeterminado: forceLoad
es true
: Blazor realiza una recarga de toda la página para la dirección URL solicitada, tanto si la navegación mejorada está disponible como si no lo está.Para actualizar la página actual, llama a NavigationManager.Refresh(bool forceLoad = false)
, que siempre realiza una navegación mejorada, en caso de que esté disponible. Si la navegación mejorada no está disponible, Blazor realiza una recarga de toda la página.
Navigation.Refresh();
Pasa true
al parámetro forceLoad
para asegurarte de que siempre se realiza la recarga de una página completa, ni siquiera si la navegación mejorada está disponible:
Navigation.Refresh(true);
La navegación mejorada está activada por defecto, pero puede controlarse jerárquicamente y por enlace mediante el data-enhance-nav
atributo HTML.
Los siguientes ejemplos deshabilitan la navegación mejorada:
<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>
Si el destino noBlazor es un punto de conexión, no se aplica la navegación mejorada, y el JavaScript del lado del cliente reintenta como una carga de página completa. Esto asegura que no haya confusión en el marco sobre las páginas externas que no deben ser parcheados en una página existente.
Para habilitar la administración mejorada de formularios, agrega el parámetro Enhance a EditForm los formularios o el atributo data-enhance
a los formularios HTML (<form>
):
<EditForm ... Enhance ...>
...
</EditForm>
<form ... data-enhance ...>
...
</form>
El control mejorado de formularios no es jerárquico y no fluye a formularios secundarios:
No admitido: no se puede establecer la navegación mejorada en el elemento antecesor de un formulario para habilitar la navegación mejorada para el formulario.
<div ... data-enhance ...>
<form ...>
<!-- NOT enhanced -->
</form>
</div>
Los envíos de formularios mejorados solo funcionan con Blazor puntos de conexión. La publicación de un formulario mejorado en un noBlazor punto de conexión produce un error.
Para deshabilitar la navegación mejorada:
false
: Enhance="false"
).<form>
, elimina el atributo data-enhance
del elemento formulario (o configúralo a false
: data-enhance="false"
).Blazor navegación mejorada y el control de formularios pueden deshacer cambios dinámicos en el DOM si el contenido actualizado no forma parte de la renderización del servidor. Para conservar el contenido de un elemento, utiliza el atributo data-permanent
.
En el siguiente ejemplo, el contenido del elemento <div>
se actualiza dinámicamente mediante un script cuando se carga la página:
<div data-permanent>
...
</div>
Una vez que Blazor se ha iniciado en el cliente, puedes utilizar el evento enhancedload
para escuchar las actualizaciones de la página mejorada. Esto permite volver a aplicar cambios en el DOM que pueden haber sido deshechos por una actualización de página mejorada.
Blazor.addEventListener('enhancedload', () => console.log('Enhanced update!'));
Para deshabilitar la navegación mejorada y la administración de formularios de forma global, consulta Inicio de ASP.NET Core Blazor.
La navegación mejorada con representación estática del lado del servidor (SSR estática) requiere una atención especial al cargar JavaScript. Para obtener más información, consulta ASP.NET Core Blazor JavaScript con representación estática del lado servidor.
En función del URI base de la aplicación, ToBaseRelativePath convierte un URI absoluto en un URI relativo al prefijo de URI base.
Considera el ejemplo siguiente:
try
{
baseRelativePath = Navigation.ToBaseRelativePath(inputURI);
}
catch (ArgumentException ex)
{
...
}
Si el URI base de la aplicación es https://localhost:8000
, se obtienen los siguientes resultados:
https://localhost:8000/segment
en inputURI
en un baseRelativePath
de segment
.https://localhost:8000/segment1/segment2
en inputURI
en un baseRelativePath
de segment1/segment2
.Si el URI base de la aplicación no coincide con el URI base de inputURI
, se produce un ArgumentException.
Pasar los resultados de https://localhost:8001/segment
en inputURI
en la siguiente excepción:
System.ArgumentException: 'The URI 'https://localhost:8001/segment' is not contained by the base URI 'https://localhost:8000/'.'
NavigationManager usa laHistory API del explorador para mantener el estado del historial de navegación asociado a cada cambio de ubicación realizado por la aplicación. Mantener el estado del historial es especialmente útil en escenarios de redirección externa como, por ejemplo, al autenticar usuarios con proveedores de identidad externos. Para obtener información adicional, consulta la sección Opciones de navegación.
Pasa NavigationOptions a NavigateTo para controlar los siguientes comportamientos:
false
.false
, se anexa la nueva entrada a la pila del historial. El valor predeterminado es false
.Navigation.NavigateTo("/path", new NavigationOptions
{
HistoryEntryState = "Navigation state"
});
Para obtener información adicional sobre cómo obtener el estado asociado a la entrada del historial de destino en el manejo de los cambios de ubicación, consulta la sección Controlar o impedir cambios de ubicación.
Utiliza el atributo [SupplyParameterFromQuery]
para especificar que un parámetro del componente procede de la cadena de consulta.
Usa el atributo [SupplyParameterFromQuery]
con el atributo [Parameter]
para especificar que un parámetro de componente de un componente enrutable puede proceder de la cadena de consulta.
Nota
Los parámetros de componente solo pueden recibir valores de parámetro de consulta en componentes enrutables con una directiva @page
.
Solo los componentes enrutables reciben directamente parámetros de consulta para evitar la subvertir el flujo de información de arriba abajo y dejar claro el orden de procesamiento de los parámetros, tanto por el marco como por la aplicación. Este diseño evita errores sutiles en el código de la aplicación que se escribió suponiendo un orden de procesamiento de parámetros específico. Puedes definir parámetros en cascada personalizados o asignarlos directamente a parámetros de componentes normales para pasar valores de parámetros de consulta a componentes no enrutables.
Los parámetros de componente proporcionados a partir de la cadena de consulta admiten los tipos siguientes:
bool
, DateTime
, decimal
, double
, float
, Guid
int
, , long
, . string
El formato de referencia cultural invariable correcto se aplica al tipo especificado (CultureInfo.InvariantCulture).
Especifica la propiedad [SupplyParameterFromQuery]
del atributo Name para usar un nombre de parámetro de consulta diferente al nombre del parámetro de componente. En el ejemplo siguiente, el nombre en C# del parámetro de componente es {COMPONENT PARAMETER NAME}
. Se especifica otro nombre de parámetro de consulta para el marcador de posición {QUERY PARAMETER NAME}
:
A diferencia de las propiedades de parámetros de componentes ([Parameter]
), las propiedades [SupplyParameterFromQuery]
se pueden marcar con private
además de con public
.
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
private string? {COMPONENT PARAMETER NAME} { get; set; }
Al igual que las propiedades de parámetros de componentes ([Parameter]
), las propiedades [SupplyParameterFromQuery]
son siempre propiedades public
en .NET 6/7. En .NET 8 o posterior, las propiedades [SupplyParameterFromQuery]
se pueden marcar con public
o private
.
[Parameter]
[SupplyParameterFromQuery(Name = "{QUERY PARAMETER NAME}")]
public string? {COMPONENT PARAMETER NAME} { get; set; }
En el ejemplo siguiente con una dirección URL de /search?filter=scifi%20stars&page=3&star=LeVar%20Burton&star=Gary%20Oldman
:
Filter
se resuelve en scifi stars
.Page
se resuelve en 3
.Stars
se rellena a partir de parámetros de consulta denominados star
(Name = "star"
) y se resuelve en LeVar Burton
y Gary Oldman
.Nota
Los parámetros de cadena de consulta del siguiente componente de página enrutable también funcionan en un componente no enrutable sin una @page
directiva (por ejemplo, Search.razor
para un componente compartido Search
usado en otros componentes).
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; }
}
Usa GetUriWithQueryParameter para agregar, cambiar o quitar uno o varios parámetros de consulta en la dirección URL actual:
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameter("{NAME}", {VALUE})
Para el ejemplo anterior:
{NAME}
especifica el nombre del parámetro de consulta. El marcador de posición {VALUE}
especifica el valor como un tipo admitido. Los tipos admitidos se enumeran más adelante en esta sección.null
.Llama a GetUriWithQueryParameters para crear un URI construido a partir de Uri con varios parámetros agregados, actualizados o quitados. En cada valor, el marco usa value?.GetType()
para determinar el tipo de tiempo de ejecución para cada parámetro de consulta y selecciona el formato invariable de referencia cultural correcto. El marco genera un error para los tipos no admitidos.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters({PARAMETERS})
El marcador de posición {PARAMETERS}
es IReadOnlyDictionary<string, object>
.
Pasa una cadena de URI a GetUriWithQueryParameters para generar uno nuevo a partir de un URI proporcionado con varios parámetros agregados, actualizados o quitados. En cada valor, el marco usa value?.GetType()
para determinar el tipo de tiempo de ejecución para cada parámetro de consulta y selecciona el formato invariable de referencia cultural correcto. El marco genera un error para los tipos no admitidos. Los tipos admitidos se enumeran más adelante en esta sección.
@inject NavigationManager Navigation
...
Navigation.GetUriWithQueryParameters("{URI}", {PARAMETERS})
{URI}
es el URI con o sin una cadena de consulta.{PARAMETERS}
es IReadOnlyDictionary<string, object>
.Los tipos admitidos son idénticos a los de las restricciones de ruta:
bool
DateTime
decimal
double
float
Guid
int
long
string
Los tipos no admitidos incluyen:
Aviso
Con la compresión, que está habilitada de forma predeterminada, evita crear componentes interactivos del lado servidor (autenticados o autorizados) seguros que representen datos de orígenes que no sean de confianza. Los orígenes que no son de confianza incluyen parámetros de ruta, cadenas de consulta, datos de interoperabilidad JS y cualquier otro origen de datos que un usuario de terceros pueda controlar (bases de datos, servicios externos). Para obtener más información, consulta Guía de ASP.NETBlazorSignalR y Guía de mitigación de amenazas de representación interactiva del lado servidor para ASP.NET Core Blazor.
Navigation.GetUriWithQueryParameter("full name", "Morena Baccarin")
Dirección URL actual | Dirección URL generada |
---|---|
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 |
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin")
Dirección URL actual | Dirección URL generada |
---|---|
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 |
Navigation.GetUriWithQueryParameter("full name", (string)null)
Dirección URL actual | Dirección URL generada |
---|---|
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/ |
En el ejemplo siguiente:
name
se quita, si está presente.age
se agrega con un valor de 25
(int
), si no está presente. Si está presente, age
se actualiza a un valor de 25
.eye color
se agrega o actualiza a un valor de green
.Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["name"] = null,
["age"] = (int?)25,
["eye color"] = "green"
})
Dirección URL actual | Dirección URL generada |
---|---|
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 |
En el ejemplo siguiente:
full name
se agrega o actualiza a Morena Baccarin
, un valor único.ping
se agregan o reemplazan por 35
, 16
, 87
y 240
.Navigation.GetUriWithQueryParameters(
new Dictionary<string, object?>
{
["full name"] = "Morena Baccarin",
["ping"] = new int?[] { 35, 16, null, 87, 240 }
})
Dirección URL actual | Dirección URL generada |
---|---|
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 |
Para navegar con una cadena de consulta agregada o modificada, pasa una dirección URL generada a NavigateTo.
En el ejemplo siguiente se llama a:
name
con un valor de Morena Baccarin
.Navigation.NavigateTo(
Navigation.GetUriWithQueryParameter("name", "Morena Baccarin"));
La cadena de consulta de una solicitud se obtiene de la propiedad NavigationManager.Uri:
@inject NavigationManager Navigation
...
var query = new Uri(Navigation.Uri).Query;
Para analizar los parámetros de una cadena de consulta, un enfoque consiste en usar URLSearchParams
con la interoperabilidad de JavaScript (JS):
export createQueryString = (string queryString) => new URLSearchParams(queryString);
Para obtener más información sobre el aislamiento de JavaScript con módulos de JavaScript, consulta Llamada a funciones de JavaScript desde métodos de .NET en Blazor de ASP.NET Core.
Ve a un elemento con nombre mediante los siguientes enfoques con una referencia hash (#
) al elemento. Las rutas a los elementos dentro del componente y las rutas a los elementos de los componentes externos usan rutas de acceso relativas a la raíz. Una barra diagonal inicial (/
) es opcional.
Los ejemplos de cada uno de los enfoques siguientes muestran la navegación a un elemento con un id
de targetElement
en el componente Counter
:
Elemento delimitador (<a>
) con href
:
<a href="/counter#targetElement">
Componente NavLink con href
:
<NavLink href="/counter#targetElement">
NavigationManager.NavigateTo pasando la URL relativa:
Navigation.NavigateTo("/counter#targetElement");
En el ejemplo siguiente se muestra el enrutamiento con hash a encabezados H2 con nombre dentro de un componente y a componentes externos.
En los componentes Home
(Home.razor
) y Counter
(Counter.razor
), coloca el marcado siguiente en la parte inferior del marcado de componente existente para que actúe como destinos de navegación. <div>
crea un espacio vertical artificial para demostrar el comportamiento del desplazamiento del explorador:
<div class="border border-info rounded bg-info" style="height:500px"></div>
<h2 id="targetElement">Target H2 heading</h2>
<p>Content!</p>
Agrega el siguiente componente HashedRouting
a la aplicación.
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");
}
}
Si se produce un retraso significativo durante la navegación, por ejemplo durante la carga diferida de ensamblados en una aplicación Blazor WebAssembly o por una conexión de red lenta a una aplicación Blazor del lado del servidor, el componente Router puede indicar al usuario que se está produciendo una transición de página.
En la parte superior del componente que especifica el componente Router, agrega una directiva @using
para el espacio de nombres Microsoft.AspNetCore.Components.Routing:
@using Microsoft.AspNetCore.Components.Routing
Proporciona contenido al parámetro Navigating para que se muestre durante los eventos de transición de página.
En el contenido del elemento enrutador (<Router>...</Router>
):
<Navigating>
<p>Loading the requested page…</p>
</Navigating>
Para obtener un ejemplo en el que se usa la propiedad Navigating, consulta Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.
El componente Router admite una característica OnNavigateAsync. El controlador OnNavigateAsync se invoca cuando el usuario:
<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)
{
...
}
}
Para obtener un ejemplo en el que se usa OnNavigateAsync, consulta Ensamblados de carga diferida en Blazor WebAssembly de ASP.NET Core.
Al representar previamente en el servidor, OnNavigateAsync se ejecuta dos veces:
Para evitar que el código del desarrollador en OnNavigateAsync se ejecute dos veces, el componente Routes
puede almacenar NavigationContext para su uso en el método del ciclo de vida OnAfterRender{Async}
, donde se puede comprobar firstRender
. Para obtener más información, consulta Representación previa con interoperabilidad de JavaScript.
Para evitar que el código de desarrollador en OnNavigateAsync se ejecute dos veces, el componente App
puede almacenar NavigationContext para su uso en OnAfterRender{Async}
, donde firstRender
se puede comprobar. Para obtener más información, consulta Representación previa con interoperabilidad de JavaScript.
El objeto NavigationContext pasado a la devolución de llamada de OnNavigateAsync contiene un elemento CancellationToken que se establece cuando se produce un nuevo evento de navegación. La devolución de llamada de OnNavigateAsync debe iniciarse cuando se establece este token de cancelación para evitar que continúe la ejecución de la devolución de llamada de OnNavigateAsync en una navegación no actualizada.
Si un usuario navega a un punto de conexión, pero inmediatamente después navega a un nuevo punto de conexión, la aplicación no debe seguir ejecutando la devolución de llamada OnNavigateAsync para el primer punto de conexión.
En el ejemplo siguiente:
PostAsJsonAsync
, que puede cancelar el POST si el usuario se desplaza fuera del punto de conexión /about
./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
Cuando no se ejecuta si el token de cancelación de NavigationContext se cancela, puede resultar en un comportamiento imprevisto, como la representación de un componente de una navegación anterior.
RegisterLocationChangingHandler registra un controlador para procesar los eventos de navegación entrantes. El contexto del controlador proporcionado porLocationChangingContext incluye las siguientes propiedades:
Un componente puede registrar varios controladores de cambio de ubicación en el método de ciclo de vida de OnAfterRender{Async}
. La navegación invoca todos los controladores de cambio de ubicación registrados en toda la aplicación (en varios componentes) y cualquier navegación interna los ejecuta en paralelo. Además de NavigateTo, los controladores se invocan:
Los controladores solo se ejecutan en la navegación interna dentro de la aplicación. Si el usuario selecciona un vínculo que lleva a un sitio diferente o cambia la barra de direcciones a otro sitio manualmente, los controladores de cambio de ubicación no se ejecutarán.
Implementa IDisposable y elimina los controladores registrados para anular su registro. Para obtener más información, consulta Ciclo de vida de componentes Razor de ASP.NET Core.
Importante
No intentes ejecutar tareas de limpieza a través de la interoperabilidad de JavaScript (JS) al controlar los cambios de ubicación. Usa el patrón MutationObserver
en JS en el cliente. Para obtener más información, consulta Interoperabilidad de JavaScript en Blazor de ASP.NET Core (interoperabilidad de JS).
En el ejemplo siguiente, se registra un controlador de cambio de ubicación en eventos de navegación.
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();
}
Dado que la navegación interna se puede cancelar de forma asincrónica, pueden solaparse varias llamadas a controladores registrados. Por ejemplo, se pueden producir varias llamadas de controlador cuando el usuario selecciona rápidamente el botón Atrás en una página o selecciona varios vínculos antes de ejecutar una navegación. A continuación se muestra un resumen de la lógica de navegación asincrónica:
Para obtener información adicional sobre cómo pasar NavigationOptions a NavigateTo para controlar las entradas y el estado de la pila del historial de navegación, consulta la sección Opciones de navegación.
Para obtener código de ejemplo adicional, consulta NavigationManagerComponent
en BasicTestApp
(origen de referencia dotnet/aspnetcore
).
Nota
Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, usa la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, consulta Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).
El componente NavigationLock
intercepta los eventos de navegación siempre que se represente, "bloqueando" de forma eficaz cualquier navegación determinada hasta que se tome una decisión para continuar o cancelar. Usa NavigationLock
cuando la interceptación de navegación se pueda limitar a la duración de un componente.
Parámetros de NavigationLock:
false
. Mostrar el diálogo de confirmación requiere una interacción inicial del usuario con la página antes de desencadenar la navegación externa con la URL de la barra de direcciones del explorador. Para obtener información adicional sobre el requisito de interacción, consulta Ventana: evento beforeunload
(documentación de MDN).En el componente NavLock
siguiente:
https://www.microsoft.com
se realice correctamente.confirm
.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();
}
}
}
Para obtener código de ejemplo adicional, consulta el componenteConfigurableNavigationLock
en BasicTestApp
(origen de referencia dotnet/aspnetcore
).
Usa un componente NavLink en lugar de los elementos de hipervínculo HTML (<a>
) cuando cree vínculos de navegación. Un componente NavLink se comporta igual que un elemento <a>
, salvo que alterna una clase CSS active
en función de si su elemento href
coincide con la dirección URL actual. La clase active
ayuda a un usuario a entender qué página es la página activa entre los vínculos de navegación mostrados. Opcionalmente, asigna un nombre de clase CSS a NavLink.ActiveClass para aplicar una clase CSS personalizada al vínculo representado cuando la ruta actual coincida con href
.
Hay dos opciones de NavLinkMatch que se pueden asignar al atributo Match
del elemento <NavLink>
:
En el ejemplo anterior, el HomeNavLinkhref=""
coincide con la dirección URL principal y solo recibe la clase CSS active
en la ruta de acceso base predeterminada de la aplicación (/
). El segundo elemento NavLink recibe la clase active
cuando el usuario visita una dirección URL con un prefijo component
(por ejemplo, /component
y /component/another-segment
).
Se pasan más atributos del componente NavLink a la etiqueta delimitadora representada. En el siguiente ejemplo, el componente NavLink incluye el atributo target
:
<NavLink href="example-page" target="_blank">Example page</NavLink>
Se representa el siguiente marcado HTML:
<a href="example-page" target="_blank">Example page</a>
Aviso
Debido a la forma en que Blazor representa el contenido secundario, la representación de componentes NavLink
dentro de un bucle for
requiere una variable de índice local si se usa la variable de bucle incremental en el contenido del componente NavLink
(secundario):
@for (int c = 1; c < 4; c++)
{
var ct = c;
<li ...>
<NavLink ...>
<span ...></span> Product #@ct
</NavLink>
</li>
}
El uso de una variable de índice en este escenario es un requisito para cualquier componente secundario que use una variable de bucle en su contenido secundario, no solo para el componente NavLink
.
También puedes usar un bucle foreach
con Enumerable.Range:
@foreach (var c in Enumerable.Range(1, 3))
{
<li ...>
<NavLink ...>
<span ...></span> Product #@c
</NavLink>
</li>
}
Las entradas de componente NavLink se pueden crear dinámicamente a partir de los componentes de la aplicación a través de la reflexión. En el siguiente ejemplo se muestra el enfoque general para una mayor personalización.
Para la siguiente demostración, se usa una convención de nomenclatura estándar coherente para los componentes de la aplicación:
Pages/ProductDetail.razor
.ProductDetail
con una plantilla de ruta de /product-detail
(@page "/product-detail"
) en un explorador en la dirección URL /product-detail
relativa.†Pascal Case (letra mayúscula) es una convención de nomenclatura sin espacios y signos de puntuación y con la primera letra de cada palabra en mayúsculas, incluida la primera palabra.
‡Kebab case es una convención de nomenclatura sin espacios y signos de puntuación que usa letras minúsculas y guiones entre palabras.
En el marcado Razor del componente NavMenu
(NavMenu.razor
) en la página Home
predeterminada, se agregan componentes NavLink desde una colección:
<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>
Método GetRoutableComponents
del bloque @code
:
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);
En el ejemplo anterior no se incluyen las siguientes páginas en la lista representada de componentes:
Home
: la página aparece por separado de los vínculos generados automáticamente porque debe aparecer en la parte superior de la lista y establecer el parámetro Match
.Error
: la página de error solo se navega por el marco de trabajo y no debe aparecer.Para obtener un ejemplo del código anterior en una aplicación de ejemplo que puedes ejecutar localmente, obtén la aplicación de muestra Blazor Web App o Blazor WebAssembly.
Esta sección se aplica a las Blazor Web App que funcionan a través de un circuito.
Esta sección es aplicable a aplicaciones Blazor Server.
Blazor Web App se integra en el enrutamiento de punto de conexión de ASP.NET Core. Una aplicación ASP.NET Core está configurada para aceptar conexiones entrantes de componentes interactivos con MapRazorComponents en el archivo Program
. El componente raíz predeterminado (primer componente cargado) es el App
(App.razor
):
app.MapRazorComponents<App>();
Blazor Server se integra en el enrutamiento de puntos de conexión de ASP.NET Core. Una aplicación ASP.NET Core está configurada para aceptar conexiones entrantes de componentes interactivos con MapBlazorHub en el archivo Program
:
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
Blazor Server se integra en el enrutamiento de puntos de conexión de ASP.NET Core. Una aplicación ASP.NET Core está configurada para aceptar conexiones entrantes de componentes interactivos con MapBlazorHub en Startup.Configure
.
La configuración típica consiste en enrutar todas las solicitudes a una página de Razor, que actúa como el host del lado servidor de la aplicación Blazor Server. Convencionalmente, la página del host se suele llamar _Host.cshtml
en la carpeta Pages
de la aplicación.
La ruta especificada en el archivo de host se denomina ruta de reserva porque tiene una prioridad baja en la búsqueda de rutas, y se solo se usa cuando no se encuentran coincidencias con otras rutas. Esto permite a la aplicación usar otros controladores y páginas sin interferir con el enrutamiento de componentes en la aplicación Blazor Server.
Para información sobre cómo configurar MapFallbackToPage para el hospedaje de servidores de direcciones URL no raíz, consulte Hospedaje e implementación de ASP.NET CoreBlazor.
Comentarios de ASP.NET Core
ASP.NET Core é un proxecto de código aberto. Selecciona unha ligazón para ofrecer comentarios:
Evento
Campionato do Mundo de Power BI DataViz
Feb 14, 4 PM - Mar 31, 4 PM
Con 4 posibilidades de entrar, poderías gañar un paquete de conferencias e facelo ao Live Grand Finale en Las Vegas
Máis informaciónFormación
Módulo
Uso de páginas, enrutamiento y diseños para mejorar la navegación de Blazor - Training
Obtenga información sobre cómo optimizar la navegación de la aplicación, usar parámetros de la dirección URL y crear diseños reutilizables en una aplicación web Blazor.
Documentación
Modos de representación de ASP.NET Core Blazor
Aprende sobre los modos de representación Blazor y cómo aplicarlos en Blazor Web App.
Control del contenido head en aplicaciones Blazor de ASP.NET Core
Obtenga información sobre cómo controlar el contenido head en aplicaciones Blazor, incluida la forma de establecer el título de la página desde un componente.
Diseños de ASP.NET Core Blazor
Aprende a crear componentes de diseño reutilizables para aplicaciones de Blazor.