Modos de representación de ASP.NET Core Blazor
En este artículo se explica el control de la representación de componentes Razor en Blazor Web App, ya sea en tiempo de compilación o runtime.
Esta guía no se aplica a las aplicaciones Blazor WebAssembly independientes. Las aplicaciones Blazor WebAssembly solo se representan en el cliente mediante un entorno de ejecución basado en WebAssembly del lado cliente y no tienen ningún concepto de modo de representación. Si se aplica un modo de representación a un componente de una aplicación Blazor WebAssembly, la designación del modo de representación no influye en la representación del componente.
Modos de representación
Cada componente de una Blazor Web App adopta un modo de representación para determinar el modelo de hospedaje que usa, dónde se representa y si es interactivo o no.
En la tabla siguiente se muestran los modos de representación disponibles para representar componentes Razor en una Blazor Web App. Para aplicar un modo de representación a un componente, use la directiva @rendermode
en la instancia del componente o en la definición del componente. Más adelante en este artículo, se muestran ejemplos para cada escenario de modo de representación.
Nombre | Descripción | Ubicación de representación | Interactive |
---|---|---|---|
Servidor estático | Representación estática del lado servidor (SSR estática) | Servidor | No |
Servidor interactivo | Representación interactiva del lado servidor (SSR interactiva) mediante Blazor Server. | Server | Sí |
WebAssembly interactivo | Representación del lado cliente (CSR) mediante Blazor WebAssembly†. | Remoto | Sí |
Automático interactivo | SSR interactiva mediante Blazor Server inicialmente y, a continuación, CSR en las visitas posteriores después de descargar la agrupación de Blazor. | Servidor y, a continuación, cliente | Sí |
†Se supone que la representación del lado cliente (CSR) es interactiva. La "representación interactiva del lado cliente" y la "CSR interactiva " no se usan en el sector ni en la documentación de Blazor.
La representación previa está habilitada de forma predeterminada para componentes interactivos. Más adelante en este artículo se proporcionan instrucciones sobre el control de la representación previa. Para conocer la terminología general del sector sobre los conceptos de representación de cliente y servidor, consulte los aspectos básicos de Blazor con ASP.NET Core.
En los ejemplos siguientes se muestra cómo establecer el modo de representación del componente con algunas características básicas del componente Razor.
Para probar los comportamientos del modo de representación localmente, puedes colocar los siguientes componentes en una aplicación creada a partir de la plantilla de proyecto de Blazor Web App. Al crear la aplicación, seleccione las opciones en los menús desplegables (Visual Studio) o aplique las opciones de la CLI (.NET CLI) para habilitar la interactividad del lado servidor y del lado cliente. Para obtener instrucciones sobre cómo crear una Blazor Web App, consulta Herramientas para ASP.NET Core Blazor.
Habilitar la compatibilidad con modos de representación interactivos
Una Blazor Web App debe configurarse para admitir modos de representación interactivos. Las extensiones siguientes se aplican automáticamente a las aplicaciones creadas a partir de la plantilla de proyecto de Blazor Web App durante la creación de la aplicación. Los componentes individuales siempre deben declarar su modo de representación según la sección Modos de representación una vez que los puntos de conexión y los servicios del componente estén configurados en el archivo Program
de la aplicación.
Los servicios de los componentes Razor se agregan mediante una llamada a AddRazorComponents.
Extensiones del generador de componentes:
- AddInteractiveServerComponents agrega servicios para admitir la representación de los componentes del Servidor interactivo.
- AddInteractiveWebAssemblyComponents agrega servicios para admitir la representación de los componentes de WebAssembly interactivo.
MapRazorComponents detecta los componentes disponibles y especifica el componente raíz de la aplicación (el primer componente cargado), que de forma predeterminada es el componente App
(App.razor
).
Extensiones del generador de convención de punto de conexión:
- AddInteractiveServerRenderMode configura la representación interactiva del lado servidor (SSR interactiva) para la aplicación.
- AddInteractiveWebAssemblyRenderMode configura el modo de representación de WebAssembly interactivo para la aplicación.
Nota:
Para obtener orientación sobre la ubicación de la API en los ejemplos siguientes, inspecciona el archivo Program
de una aplicación generada a partir de la plantilla de proyecto de Blazor Web App. Para obtener instrucciones sobre cómo crear una Blazor Web App, consulta Herramientas para ASP.NET Core Blazor.
Ejemplo 1: la siguiente API de archivo Program
agrega servicios y configuración para habilitar la SSR interactiva:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
Ejemplo 2: la siguiente API de archivo Program
agrega servicios y configuración para habilitar el modo de representación WebAssembly interactivo:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode();
Ejemplo 3: la siguiente API de archivo Program
agrega servicios y configuración para habilitar los modos de representación Servidor interactivo, WebAssembly interactivo y Automático interactivo:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode();
Blazor usa el modelo de hospedaje Blazor WebAssembly para descargar y ejecutar componentes que usan el modo de representación WebAssembly interactivo. Se requiere un proyecto de cliente independiente para configurar el hospedaje Blazor WebAssembly para estos componentes. El proyecto de cliente contiene el código de inicio del host Blazor WebAssembly y configura el entorno de ejecución de .NET para ejecutarse en un explorador. La plantilla de Blazor Web App agrega este proyecto de cliente por ti al seleccionar la opción para habilitar la interactividad de WebAssembly. Los componentes que usen el modo de representación WebAssembly interactivo deben compilarse a partir del proyecto de cliente, por lo que se incluyen en el lote de aplicaciones descargado.
Aplicar un modo de representación a una instancia de componente
Para aplicar un modo de representación a una instancia de componente, usa el atributo de directiva @rendermode
Razor donde se usa el componente.
En el ejemplo siguiente, la representación interactiva del lado servidor (SSR interactiva) se aplica a la instancia del componente Dialog
:
<Dialog @rendermode="InteractiveServer" />
Nota:
Las plantillas Blazor incluyen una directiva estática using
para RenderMode en el archivo de _Imports
la aplicación (Components/_Imports.razor
) para una sintaxis más corta @rendermode
:
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Sin la directiva anterior, los componentes deben especificar la clase estática RenderMode en la sintaxis @rendermode
:
<Dialog @rendermode="RenderMode.InteractiveServer" />
También puedes hacer referencia a instancias del modo de representación personalizado creadas directamente con la configuración personalizada. Para obtener más información, consulta la sección Modos de representación abreviados personalizados más adelante en este artículo.
Aplicar un modo de representación a una definición de componente
Para especificar el modo de representación de un componente como parte de su definición, use la directiva @rendermode
Razor y el atributo de modo de representación correspondiente.
@page "..."
@rendermode InteractiveServer
La aplicación de un modo de representación a una definición de componente se usa normalmente al aplicar un modo de representación a una página específica. Las páginas enrutables usan el mismo modo de representación que el componente Router que ha representado la página.
Técnicamente, @rendermode
es una Razordirectiva y un Razoratributo de directiva. La semántica es similar, pero hay diferencias. La directiva @rendermode
está en la definición del componente, por lo que la instancia del modo de representación a la que se hace referencia debe ser estática. El atributo de directiva @rendermode
puede tomar cualquier instancia del modo de representación.
Nota:
Los autores de componentes deben evitar acoplar la implementación de un componente a un modo de representación específico. En su lugar, los autores de componentes normalmente deben diseñar componentes para admitir cualquier modo de representación o modelo de hospedaje. La implementación de un componente debe evitar suposiciones sobre dónde se ejecuta (servidor o cliente) y debe degradarse correctamente cuando se representa estáticamente. Es posible que sea necesario especificar el modo de representación en la definición del componente si no se crea una instancia del componente directamente (por ejemplo, con un componente de página enrutable) o para especificar un modo de representación para todas las instancias del componente.
Aplicación de un modo de representación en toda la aplicación
Para establecer el modo de representación para toda la aplicación, indica el modo de representación en el componente interactivo de nivel más alto de la jerarquía de componentes de la aplicación que no es un componente raíz.
Nota:
No se admite la creación de un componente raíz interactivo, como el componente App
. Por tanto, el componente App
no puede establecer directamente el modo de representación para toda la aplicación.
En el caso de las aplicaciones basadas en la plantilla de proyecto de Blazor Web App, suele especificarse un modo de representación asignado a toda la aplicación donde se usa el componente Routes
en el componente App
(Components/App.razor
):
<Routes @rendermode="InteractiveServer" />
El componente Router propaga su modo de representación a las páginas que enruta.
Normalmente, también debes establecer el mismo modo de representación interactivo en el componente HeadOutlet
, que también se encuentra en el componente App
de una Blazor Web App generada a partir de la plantilla del proyecto:
<HeadOutlet @rendermode="InteractiveServer" />
En el caso de las aplicaciones que adoptan un modo de representación interactivo del lado cliente (WebAssembly o Automático) y habilitan el modo de representación para toda la aplicación a través del componenteRoutes
:
- Coloca o mueve los archivos de diseño y navegación de la carpeta
Components/Layout
de la aplicación del servidor a la carpetaLayout
del proyecto.Client
. Crea una carpetaLayout
en el proyecto.Client
si todavía no existe. - Coloca o mueve los componentes de la carpeta
Components/Pages
de la aplicación del servidor a la carpetaPages
del proyecto.Client
. Crea una carpetaPages
en el proyecto.Client
si todavía no existe. - Coloca o mueve el componente
Routes
de la carpetaComponents
de la aplicación del servidor a la carpeta raíz del proyecto.Client
.
Para habilitar la interactividad global al crear una Blazor Web App:
- Visual Studio: establezca la lista desplegable Ubicación de interactividad en Global.
- CLI de .NET: usar la opción
-ai|--all-interactive
.
Para más información, vea Herramientas para ASP.NET Core Blazor.
Aplicar un modo de representación mediante programación
Las propiedades y los campos pueden asignar modos de representación.
El segundo enfoque descrito en esta sección, establecer el modo de representación por instancia de componente, es especialmente útil cuando la especificación de la aplicación llama a uno o varios componentes para adoptar SSR estática en una aplicación interactiva globalmente. Este escenario se trata en la sección páginas de SSR estática de una aplicación interactiva globalmente más adelante en este artículo.
Establecimiento del modo de representación por definición de componente
Una definición de componente puede definir un modo de representación a través de un campo privado:
@rendermode pageRenderMode
...
@code {
private static IComponentRenderMode pageRenderMode = InteractiveServer;
}
Establecimiento del modo de representación por instancia de componente
En el ejemplo siguiente, se aplica la representación interactiva del lado servidor (SSR interactiva) a cualquier solicitud.
<Routes @rendermode="PageRenderMode" />
...
@code {
private IComponentRenderMode? PageRenderMode => InteractiveServer;
}
Se proporciona información adicional sobre la propagación del modo de representación en la sección Propagación del modo de representación más adelante en este artículo. Las páginas de SSR estática de una aplicación interactiva globalmente muestran cómo usar el enfoque anterior para adoptar la SSR estática en una aplicación interactiva globalmente.
Detección de la ubicación de representación, interactividad y modo de representación asignado en tiempo de ejecución
Las propiedades ComponentBase.RendererInfo y ComponentBase.AssignedRenderMode permiten a la aplicación detectar detalles sobre la ubicación, la interactividad y el modo de representación asignado de un componente:
- RendererInfo.Name devuelve la ubicación donde se ejecuta el componente:
Static
: En el servidor (SSR) e incapaz de interactividad.Server
: En el servidor (SSR) y capaz de interactividad después de la representación previa.WebAssembly
: En el cliente (CSR) y capaz de interactividad después de la representación previa.WebView
: En el dispositivo nativo y capaz de interactividad después de la representación previa.
- RendererInfo.IsInteractive Indica si el componente admite interactividad en el momento de la representación. El valor es
true
cuando se representa de forma interactiva ofalse
al representar previamente o para SSR estático (RendererInfo.Name deStatic
). - ComponentBase.AssignedRenderMode expone el modo de representación asignado del componente:
InteractiveServer
para Interactive Server.InteractiveAuto
para Interactive Auto.InteractiveWebAssembly
para Interactive WebAssembly.
Los componentes usan estas propiedades para representar contenido en función de su ubicación o estado de interactividad. Por ejemplo, un formulario se puede deshabilitar durante la representación previa y habilitarse cuando el componente se vuelve interactivo:
<EditForm Model="Movie" ...>
<fieldset disabled="@disabled">
...
<button type="submit" >Save</button>
</fieldset>
</EditForm>
@code {
private bool disabled = true;
[SupplyParameterFromForm]
private Movie? Movie { get; set; }
protected override async Task OnInitializedAsync()
{
Movie ??= await ...;
if (RendererInfo.IsInteractive)
{
disabled = false;
}
}
}
En el ejemplo siguiente se muestra cómo representar el marcado para admitir la realización de una acción HTML normal si el componente se representa estáticamente:
@if (AssignedRenderMode is null)
{
// The render mode is Static Server
<form action="/movies">
<input type="text" name="titleFilter" />
<input type="submit" value="Search" />
</form>
}
else
{
// The render mode is Interactive Server, WebAssembly, or Auto
<input @bind="titleFilter" />
<button @onclick="FilterMovies">Search</button>
}
En el ejemplo anterior:
- Cuando el valor de AssignedRenderMode es
null
, el componente adopta SSR estático. Blazor control de eventos no funciona en un explorador con SSR estático, por lo que el componente envía un formulario (solicitud GET) con una cadena de consultatitleFilter
establecida en el valor de<input>
del usuario. El componenteMovie
(/movie
) puede leer la cadena de consulta y procesar el valor detitleFilter
para representar el componente con los resultados filtrados. - De lo contrario, el modo de representación es cualquiera de
InteractiveServer
,InteractiveWebAssembly
, oInteractiveAuto
. El componente es capaz de usar un delegado de controlador de eventos (FilterMovies
) y el valor enlazado al elemento<input>
(titleFilter
) para filtrar películas de forma interactiva a través de la conexión de SignalR en segundo plano.
Ejemplos de documentación de Blazor para Blazor Web App
Cuando se usa Blazor Web App, la mayoría de los componentes de ejemplo de documentación de Blazor requieren interactividad para funcionar y demostrar los conceptos descritos en los artículos. Al probar un componente de ejemplo proporcionado por un artículo, asegúrese de que, o bien la aplicación adopta la interactividad global, o bien el componente adopta un modo de representación interactivo.
Representación previa
La representación previa es el proceso de representación inicial del contenido de la página en el servidor sin habilitar controladores de eventos para controles representados. El servidor genera la interfaz de usuario HTML de la página lo antes posible en respuesta a la solicitud inicial, lo que hace que la aplicación se sienta más sensible a los usuarios. La representación previa también puede mejorar la optimización del motor de búsqueda (SEO) mediante la representación del contenido de la respuesta HTTP inicial que los motores de búsqueda usan para calcular la clasificación de página.
La representación previa está habilitada de forma predeterminada para componentes interactivos.
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, incluidas las de navegación mejorada. Para obtener más información, consulte enrutamiento estático frente a interactivo, Enrutamiento interactivo y representación previa y Navegación mejorada y control de formularios.
Deshabilitar la representación previa mediante las siguientes técnicas solo surte efecto para los modos de representación de nivel superior. Si un componente primario especifica un modo de representación, se omite la configuración de representación previa de sus elementos secundarios. Este comportamiento está bajo investigación para posibles cambios con la versión de .NET 10 en noviembre de 2025.
Para deshabilitar la representación previa de una instancia de componente, pasa la marca prerender
con un valor de false
para representar el modo:
<... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
<... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
<... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />
Para deshabilitar la representación previa en una definición de componente:
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
@rendermode @(new InteractiveAutoRenderMode(prerender: false))
Para deshabilitar la representación previa para toda la aplicación, indica el modo de representación en el componente interactivo de nivel más alto de la jerarquía de componentes de la aplicación que no es un componente raíz.
En el caso de las aplicaciones basadas en la plantilla de proyecto de Blazor Web App, se especifica un modo de representación asignado a toda la aplicación donde se usa el componente Routes
en el componente App
(Components/App.razor
): En el ejemplo siguiente se establece el modo de representación de la aplicación en Servidor interactivo con la representación previa deshabilitada:
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Además, deshabilita la representación previa para el HeadOutlet
componente en el componente App
:
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
No se admite la creación de un componente raíz, como el componente App
, interactivo con la directiva @rendermode
en la parte superior del archivo de definición del componente raíz (.razor
). Por lo tanto, el componente App
no puede deshabilitar la representación previa directamente.
Representación estática del lado servidor (SSR estática)
Los componentes usan la representación estática del lado servidor (SSR estática). El componente se representa en el flujo de respuesta y la interactividad no está habilitado.
En el ejemplo siguiente, no hay ninguna designación para el modo de representación del componente, de forma que el componente hereda su modo de representación del elemento primario. Como ningún componente antecesor especifica un modo de representación, el siguiente componente se representa estáticamente en el servidor. El botón no es interactivo y no llama al método UpdateMessage
cuando se selecciona. El valor de message
no cambia y el componente no se vuelve a representar en respuesta a los eventos de la interfaz de usuario.
RenderMode1.razor
:
@page "/render-mode-1"
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Si usas el componente anterior localmente en una Blazor Web App, coloca el componente en la carpeta Components/Pages
del proyecto de servidor. El proyecto de servidor es el proyecto de la solución con un nombre que no termina en .Client
. Cuando se ejecute la aplicación, ve a /render-mode-1
en la barra de direcciones del explorador.
Durante la SSR estática, las solicitudes de página de componentes Razor se procesan en el procesamiento de solicitudes de canalización de middleware de ASP.NET Core del lado servidor para el enrutamiento y la autorización. Las características de Blazor dedicadas para el enrutamiento y la autorización no están operativas porque los componentes Razor no se representan durante el procesamiento de solicitudes del lado servidor. Las características del enrutador de Blazor en el componente Routes
que no están disponibles durante la SSR estática incluyen la visualización de:
Contenido no autorizado (
<NotAuthorized>...</NotAuthorized>
) (NotAuthorized): las Blazor Web App normalmente procesan solicitudes no autorizadas en el servidor personalizando el comportamiento del middleware de autorización.Contenido no encontrado (
<NotFound>...</NotFound>
) (NotFound): los objetos Blazor Web App normalmente procesan las solicitudes de dirección URL incorrectas en el servidor visualizando la interfaz de usuario integrada del explorador 404 o devolviendo una página 404 personalizada (u otra respuesta) mediante el middleware de ASP.NET Core (por ejemplo,UseStatusCodePagesWithRedirects
/ documentación de API).
Si la aplicación muestra interactividad a nivel raíz, el procesamiento de solicitudes de ASP.NET Core del lado servidor no está implicado después de la SSR estática inicial, lo que significa que las características de Blazor anteriores funcionan según lo previsto.
La navegación mejorada con SSR estática requiere especial atención al cargar JavaScript. Para obtener más información, consulta ASP.NET Core Blazor JavaScript con representación estática del lado servidor.
Representación interactiva del lado servidor (SSR interactiva)
La representación interactiva del lado servidor (SSR interactiva) representa el componente de forma interactiva desde el servidor mediante Blazor Server. Las interacciones del usuario se controlan a través de una conexión en tiempo real con el explorador. La conexión del circuito se establece cuando se representa el componente Servidor.
En el ejemplo siguiente, el modo de representación se establece en SSR interactiva agregando @rendermode InteractiveServer
a la definición del componente. El botón llama al método UpdateMessage
cuando se selecciona. El valor de message
cambia y el componente se vuelve a representar para actualizar el mensaje en la interfaz de usuario.
RenderMode2.razor
:
@page "/render-mode-2"
@rendermode InteractiveServer
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Si usa el componente anterior en , Blazor Web Appcoloque el componente en la carpeta del proyecto de Components/Pages
servidor. El proyecto de servidor es el proyecto de la solución con un nombre que no termina en .Client
. Cuando se ejecute la aplicación, vaya a /render-mode-2
en la barra de direcciones del explorador.
Representación del lado cliente (CSR)
La representación del lado cliente (CSR) representa el componente de forma interactiva en el cliente mediante Blazor WebAssembly. El entorno de ejecución de .NET y el lote de aplicaciones se descargan y almacenan en caché cuando el componente WebAssembly se representa inicialmente. Los componentes que usan la CSR deben compilarse a partir de un proyecto de cliente independiente que configure el host Blazor WebAssembly.
En el ejemplo siguiente, el modo de representación se configura en CSR con @rendermode InteractiveWebAssembly
. El botón llama al método UpdateMessage
cuando se selecciona. El valor de message
cambia y el componente se vuelve a representar para actualizar el mensaje en la interfaz de usuario.
RenderMode3.razor
:
@page "/render-mode-3"
@rendermode InteractiveWebAssembly
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Si usas el componente anterior localmente en una Blazor Web App, coloca el componente en la carpeta Pages
del proyecto de cliente. El proyecto de cliente es el proyecto de la solución con un nombre que termina en .Client
. Cuando se ejecute la aplicación, ve a /render-mode-3
en la barra de direcciones del explorador.
Representación automática (Automático)
El modo de representación automática (Automático) determina cómo representar el componente en el runtime. El componente se representa inicialmente con la representación interactiva del lado servidor (SSR interactiva) mediante el modelo de hospedaje Blazor Server. El runtime de .NET y el lote de aplicaciones se descargan en el cliente en segundo plano y se almacenan en caché para que se puedan usar en futuras visitas.
El modo de representación Automático nunca cambia dinámicamente el modo de representación de un componente que ya está en la página. El modo de representación Automático toma una decisión inicial sobre el tipo de interactividad que se va a usar para un componente y, después, el componente mantiene ese tipo de interactividad mientras esté en la página. Un factor de esta decisión inicial es considerar si los componentes ya existen en la página con interactividad de WebAssembly/Server. El modo Automático prefiere seleccionar un modo de representación que coincida con el de los componentes interactivos existentes. La razón por la que el modo Automático prefiere usar un modo de interactividad existente es evitar la introducción de un nuevo runtime interactivo que no comparte el estado con el runtime existente.
Los componentes que usan el modo de representación Automático deben compilarse a partir de un proyecto de cliente independiente que configure el host Blazor WebAssembly.
En el ejemplo siguiente, el componente es interactivo en todo el proceso. El botón llama al método UpdateMessage
cuando se selecciona. El valor de message
cambia y el componente se vuelve a representar para actualizar el mensaje en la interfaz de usuario. Inicialmente, el componente se representa de forma interactiva desde el servidor, pero en las visitas posteriores se representa desde el cliente después de descargar y almacenar en caché el lote de aplicaciones y el runtime de .NET.
RenderMode4.razor
:
@page "/render-mode-4"
@rendermode InteractiveAuto
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Si usas el componente anterior localmente en una Blazor Web App, coloca el componente en la carpeta Pages
del proyecto de cliente. El proyecto de cliente es el proyecto de la solución con un nombre que termina en .Client
. Cuando se ejecute la aplicación, ve a /render-mode-4
en la barra de direcciones del explorador.
Propagación del modo de representación
Los modos de representación propagan la jerarquía de componentes.
Reglas para aplicar modos de representación:
- El modo de representación predeterminado es Estático.
- Los modos de representación Servidor interactivo (InteractiveServer), WebAssembly interactivo (InteractiveWebAssembly) y Automático interactivo (InteractiveAuto) se pueden usar desde un componente, incluido el uso de diferentes modos de representación para los componentes del mismo nivel.
- No se puede cambiar a otro modo de representación interactivo en un componente secundario. Por ejemplo, un componente Servidor no puede ser un elemento secundario de un componente WebAssembly.
- Los parámetros pasados a un componente secundario interactivo a partir de un elemento primario estático deben ser serializables JSON. Esto significa que no se pueden pasar fragmentos de representación o contenido secundario de un componente primario estático a un componente secundario interactivo.
En los ejemplos siguientes se usa un componente SharedMessage
que no es enrutable ni una página. El componente SharedMessage
independiente del modo de representación no aplica un modo de representación con una directiva @attribute
. Si vas a probar estos escenarios con una Blazor Web App, coloca el siguiente componente en la carpeta Components
de la aplicación.
SharedMessage.razor
:
<p>@Greeting</p>
<button @onclick="UpdateMessage">Click me</button> @message
<p>@ChildContent</p>
@code {
private string message = "Not updated yet.";
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public string Greeting { get; set; } = "Hello!";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Herencia del modo de representación
Si el componente SharedMessage
se coloca en un componente primario representado estáticamente, el componente SharedMessage
también se representa estáticamente y no es interactivo. El botón no llama a UpdateMessage
y el mensaje no se actualiza.
RenderMode5.razor
:
@page "/render-mode-5"
<SharedMessage />
Si el componente SharedMessage
se coloca en un componente que define el modo de representación, hereda el modo de representación aplicado.
En el ejemplo siguiente, el componente SharedMessage
es interactivo a través de una conexión SignalR al cliente. El botón llama a UpdateMessage
y el mensaje se actualiza.
RenderMode6.razor
:
@page "/render-mode-6"
@rendermode InteractiveServer
<SharedMessage />
Componentes secundarios con diferentes modos de representación
En el ejemplo siguiente, ambos componentes SharedMessage
se presentan previamente y aparecen cuando la página se muestra en el explorador.
- El primer componente
SharedMessage
con la representación interactiva del lado servidor (SSR interactiva) es interactivo después de establecer el circuito SignalR. - El segundo componente
SharedMessage
con la representación del lado cliente (CSR) es interactivo después de que el lote de aplicaciones Blazor se haya descargado y el runtime de .NET esté activo en el cliente.
RenderMode7.razor
:
@page "/render-mode-7"
<SharedMessage @rendermode="InteractiveServer" />
<SharedMessage @rendermode="InteractiveWebAssembly" />
Componente secundario con un parámetro serializable
En el ejemplo siguiente se muestra un componente secundario interactivo que toma un parámetro. Los parámetros deben ser serializables.
RenderMode8.razor
:
@page "/render-mode-8"
<SharedMessage @rendermode="InteractiveServer" Greeting="Welcome!" />
No se admiten los parámetros de componentes no serializables, como el contenido secundario o un fragmento de representación. En el ejemplo siguiente, pasar contenido secundario al componente SharedMessage
produce un error de runtime.
RenderMode9.razor
:
@page "/render-mode-9"
<SharedMessage @rendermode="InteractiveServer">
Child content
</SharedMessage>
Error:
System.InvalidOperationException: no se puede pasar el parámetro "ChildContent" al componente "SharedMessage" con el modo de representación "InteractiveServerRenderMode". Esto se debe a que el parámetro es del tipo delegado "Microsoft.AspNetCore.Components.RenderFragment", que es código arbitrario y no se puede serializar.
Para eludir la limitación anterior, encapsula el componente secundario en otro componente que no tenga el parámetro. Este es el enfoque adoptado en la plantilla de proyecto de Blazor Web App con el componente Routes
(Components/Routes.razor
) para encapsular el componente Router.
WrapperComponent.razor
:
<SharedMessage>
Child content
</SharedMessage>
RenderMode10.razor
:
@page "/render-mode-10"
<WrapperComponent @rendermode="InteractiveServer" />
En el ejemplo anterior:
- El contenido secundario se pasa al componente
SharedMessage
sin generar un error de runtime. - El componente
SharedMessage
se representa de forma interactiva en el servidor.
Componente secundario con un modo de representación diferente al primario
No intentes aplicar a un componente secundario un modo de representación interactivo distinto del modo de representación de su elemento primario.
El siguiente componente produce un error de runtime cuando se representa el componente:
RenderMode11.razor
:
@page "/render-mode-11"
@rendermode InteractiveServer
<SharedMessage @rendermode="InteractiveWebAssembly" />
Error:
Cannot create a component of type 'BlazorSample.Components.SharedMessage' because its render mode 'Microsoft.AspNetCore.Components.Web.InteractiveWebAssemblyRenderMode' is not supported by Interactive Server rendering.
Páginas de SSR estática en una aplicación interactiva globalmente
Hay casos en los que la especificación de la aplicación llama a los componentes para adoptar la representación estática del lado servidor (SSR estática) y solo se ejecuta en el servidor, mientras que rest de la aplicación usará un modo de representación interactiva.
Este enfoque solo es útil cuando la aplicación tiene páginas específicas que no pueden trabajar con la representación interactiva de Servidor o WebAssembly. Por ejemplo, adopta este enfoque para las páginas que dependen de la lectura y escritura de cookies de HTTP y solo pueden funcionar en un ciclo de solicitud/respuesta en lugar de la representación interactiva. En el caso de las páginas que funcionan con la representación interactiva, no debes obligarlas a usar la representación SSR estática, ya que es menos eficaz y tiene menos capacidad de respuesta para el usuario final.
Marque cualquier Razor página de componentes con el [ExcludeFromInteractiveRouting]
atributo asignado con la @attribute
Razor directiva :
@attribute [ExcludeFromInteractiveRouting]
La aplicación del atributo hace que la navegación a la página salga del enrutamiento interactivo. La navegación entrante se ve forzada a realizar una recarga de página completa en su lugar resolviendo la página a través del enrutamiento interactivo. La recarga de página completa obliga al componente raíz de nivel superior, normalmente el componente App
(App.razor
), a volver a representar desde el servidor, lo que permite que la aplicación cambie a otro modo de representación de nivel superior.
El RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting método de extensión permite al componente detectar si el [ExcludeFromInteractiveRouting]
atributo se aplica a la página actual.
En el componente App
, usa el patrón en el ejemplo siguiente:
- Páginas que no están anotadas con el
[ExcludeFromInteractiveRouting]
atributo predeterminado para elInteractiveServer
modo de representación con interactividad global. Puedes reemplazarInteractiveServer
porInteractiveWebAssembly
oInteractiveAuto
para especificar otro modo de representación global predeterminado. - Las páginas anotadas con el
[ExcludeFromInteractiveRouting]
atributo adoptan SSR estático (PageRenderMode
se asignanull
a ).
<!DOCTYPE html>
<html>
<head>
...
<HeadOutlet @rendermode="@PageRenderMode" />
</head>
<body>
<Routes @rendermode="@PageRenderMode" />
...
</body>
</html>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? PageRenderMode
=> HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}
Una alternativa al uso del método de extensión RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting es leer manualmente los metadatos del punto de conexión mediante HttpContext.GetEndpoint()?.Metadata
.
Hay dos enfoques que se pueden adoptar para controlar detalladamente los modos de representación, cada uno de los cuales se describe en las siguientes subsecciones:
Área (carpeta) de componentes de SSR estática: tiene un área (carpeta) de la aplicación con componentes que deben adoptar la SSR estática y compartir el mismo prefijo de ruta de acceso. La aplicación controla el modo de representación globalmente estableciendo el modo de representación del componente
Routes
en el componenteApp
en función de la ruta de acceso a la carpeta.Componentes de SSR estática distribuidos por la aplicación: tiene componentes repartidos por la aplicación en varias ubicaciones que deben adoptar la SSR estática y que solo se ejecutan en el servidor. Los componentes que solo son de SSR estática no están en una sola carpeta y no comparten un prefijo de ruta de acceso común. La aplicación controla el modo de representación por componente estableciendo el modo de representación con la directiva
@rendermode
en instancias de componentes. Se usa la reflexión del componenteApp
para establecer el modo de representación en el componenteRoutes
.
En ambos casos, el componente que deba adoptar la SSR estática también deberá forzar una recarga de página completa.
En los ejemplos siguientes, se usa el parámetro en cascada HttpContext para determinar si la página se representa estáticamente. Un HttpContext null
indica que el componente se representa de forma interactiva, lo que resulta útil como señal en el código de la aplicación para desencadenar una recarga de página completa.
Área (carpeta) de componentes de SSR estática
La plantilla de proyecto de Blazor Web App usa el enfoque descrito en esta subsección con autenticación individual e interactividad global.
Un área (carpeta) de la aplicación contiene los componentes que debe adoptar la SSR estática y que solo se ejecutan en el servidor. Los componentes de la carpeta comparten el mismo prefijo de ruta de acceso. Por ejemplo, los componentes IdentityRazor de la plantilla de proyecto de Blazor Web App están en la carpeta Components/Account/Pages
y comparten el prefijo de ruta de acceso raíz /Account
.
La carpeta también contiene un archivo _Imports.razor
, que aplica un diseño de cuenta personalizado a los componentes de la carpeta:
@using BlazorSample.Components.Account.Shared
@layout AccountLayout
La carpeta Shared
mantiene el componente de diseño AccountLayout
. El componente usa HttpContext para determinar si el componente ha adoptado SSR estática. Los componentes Identity deben representarse en el servidor con la SSR estática porque establecen cookies Identity. Si el valor de HttpContext es null
, el componente se representa de forma interactiva y se realiza una recarga de página completa llamando a NavigationManager.Refresh con forceLoad
establecido en true
. Esto fuerza una representación completa de la página mediante la SSR estática.
Components/Account/Shared/AccountLayout.razor
:
@inherits LayoutComponentBase
@layout BlazorSample.Components.Layout.MainLayout
@inject NavigationManager Navigation
@if (HttpContext is null)
{
<p>Loading...</p>
}
else
{
@Body
}
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnParametersSet()
{
if (HttpContext is null)
{
Navigation.Refresh(forceReload: true);
}
}
}
Nota:
En la plantilla de proyecto de Blazor Web App, hay un segundo archivo de diseño (ManageLayout.razor
en la carpeta Components/Account/Shared
) para los componentes Identity de la carpeta Components/Account/Pages/Manage
. La carpeta Manage
tiene su propio archivo _Imports.razor
para aplicar al ManageLayout
para los componentes de la carpeta. En sus propias aplicaciones, el uso de archivos _Imports.razor
anidados es un enfoque útil para aplicar diseños personalizados a grupos de páginas.
En el componente App
, cualquier solicitud de un componente de la carpeta Account
aplica un modo de representación null
que aplica la SSR estática. Otras solicitudes de componentes reciben una aplicación global del modo de representación de SSR interactiva (InteractiveServer
).
Importante
La aplicación de un modo de representación null
no siempre aplica la SSR estática. Simplemente, ocurre que se comporta de esa manera con el enfoque que se muestra en esta sección.
Un modo de representación null
resulta prácticamente lo mismo que no especificar un modo de representación, lo que da como resultado que el componente herede el modo de representación de su elemento primario. En este caso, el componente App
se representará mediante la SSR estática, por lo que un modo de representación null
dará como resultado el componente Routes
heredando la SSR estática del componente App
. Si se especificase un modo de representación null para un componente secundario cuyo elemento primario usase un modo de representación interactiva, el elemento secundario heredará el mismo modo de representación interactiva.
Components/App.razor
:
<Routes @rendermode="RenderModeForPage" />
...
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.Request.Path.StartsWithSegments("/Account")
? null
: {INTERACTIVE RENDER MODE};
}
En el código anterior, cambia el marcador de posición {INTERACTIVE RENDER MODE}
por el valor adecuado, en función de si el rest de la aplicación debiera adoptar la representación global InteractiveServer, InteractiveWebAssembly o InteractiveAuto.
Los componentes que deben adoptar SSR estáticas en la carpeta Account
no son necesarios para establecer el diseño, que se aplica a través del archivo _Imports.razor
. Los componentes no establecen un modo de representación porque deben representarse con una SSR estática. No se debe hacer nada más para que los componentes de la carpeta Account
apliquen la SSR estática.
Componentes de SSR estática distribuidos por la aplicación
En la subsección anterior, la aplicación controla el modo de representación de los componentes estableciendo el modo de representación globalmente en el componente App
. Como alternativa, el componente App
también puede adoptar modos de representación por componente para establecer el modo de representación, lo que permite que los componentes se extiendan por la aplicación para aplicar la adopción de la SSR estática. En esta subsección se describe el enfoque.
La aplicación tiene un diseño personalizado que se puede aplicar a los componentes de la aplicación. Normalmente, un componente compartido para la aplicación se coloca en la carpeta Components/Layout
. El componente usa HttpContext para determinar si el componente ha adoptado SSR estática. Si el valor de HttpContext es null
, el componente se representa de forma interactiva y se realiza una recarga de página completa llamando a NavigationManager.Refresh con forceLoad
establecido en true
. Esto desencadena una solicitud al servidor para el componente.
Components/Layout/StaticSsrLayout.razor
:
@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager Navigation
@if (HttpContext is null)
{
<p>Loading...</p>
}
else
{
@Body
}
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnParametersSet()
{
if (HttpContext is null)
{
Navigation.Refresh(forceReload: true);
}
}
}
En el componente App
, la reflexión se usa para establecer el modo de representación. El modo de representación que se asigne al archivo de definición del componente individual se aplicará al componente Routes
.
Components/App.razor
:
<Routes @rendermode="RenderModeForPage" />
...
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.GetEndpoint()?.Metadata.GetMetadata<RenderModeAttribute>()?
.Mode;
}
Cada componente que deba adoptar la SSR estática establecerá el diseño personalizado y no especificará un modo de representación. Si no se especificase un modo de representación, se obtendrá un valor de null
de RenderModeAttribute.Mode en el componente App
, lo que no dará como resultado ningún modo de representación asignado a la instancia de componente Routes
y a la aplicación de la SSR estática.
Importante
La aplicación de un modo de representación null
no siempre aplica la SSR estática. Simplemente, ocurre que se comporta de esa manera con el enfoque que se muestra en esta sección.
Un modo de representación null
resulta prácticamente lo mismo que no especificar un modo de representación, lo que da como resultado que el componente herede el modo de representación de su elemento primario. En este caso, el componente App
se representará mediante la SSR estática, por lo que un modo de representación null
dará como resultado el componente Routes
heredando la SSR estática del componente App
. Si se especificase un modo de representación null para un componente secundario cuyo elemento primario usase un modo de representación interactiva, el elemento secundario heredará el mismo modo de representación interactiva.
No se debe hacer nada más para que los componentes apliquen la SSR estática que aplicar el diseño personalizado sin establecer un modo de representación interactiva:
@layout BlazorSample.Components.Layout.StaticSsrLayout
Los componentes interactivos de la aplicación evitan aplicar el diseño personalizado de SSR estática y solo establecen un modo de representación interactiva adecuado, que tras la reflexión del componente App
se aplica al componente Routes
:
@rendermode {INTERACTIVE RENDER MODE}
En el código anterior, cambia el marcador de posición {INTERACTIVE RENDER MODE}
por el valor adecuado, en función de si el componente debiera adoptar la representación InteractiveServer, InteractiveWebAssembly o InteractiveAuto.
Los servicios del lado cliente no se resuelven durante la representación previa
Suponiendo que la representación previa no está deshabilitada para un componente o para la aplicación, un componente del proyecto .Client
se representa previamente en el servidor. Dado que el servidor no tiene acceso a los servicios Blazor registrados del lado cliente, no es posible insertar estos servicios en un componente sin recibir un error que indica que el servicio no se puede encontrar durante la representación previa.
Por ejemplo, considera el siguiente componente Home
en el proyecto .Client
de una Blazor Web App con la representación automática interactiva o la representación interactiva de WebAssembly global. El componente intenta insertar IWebAssemblyHostEnvironment para obtener el nombre del entorno.
@page "/"
@inject IWebAssemblyHostEnvironment Environment
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<p>
Environment: @Environment.Environment
</p>
No se produce ningún error en tiempo de compilación, pero se produce un error en tiempo de ejecución durante la representación previa:
No se puede proporcionar un valor para la propiedad "Environment" en el tipo "BlazorSample.Client.Pages.Home". No hay ningún servicio registrado de tipo "Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment".
Este error se produce porque el componente debe compilarse y ejecutarse en el servidor durante la representación previa, pero IWebAssemblyHostEnvironment no es un servicio registrado en el servidor.
Si la aplicación no requiere el valor durante la representación previa, este problema se puede resolver insertando IServiceProvider para obtener el servicio en lugar del propio tipo de servicio:
@page "/"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IServiceProvider Services
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<p>
<b>Environment:</b> @environmentName
</p>
@code {
private string? environmentName;
protected override void OnInitialized()
{
if (Services.GetService<IWebAssemblyHostEnvironment>() is { } env)
{
environmentName = env.Environment;
}
}
}
Sin embargo, el enfoque anterior no es útil si la lógica requiere un valor durante la representación previa.
También puedes evitar el problema si deshabilita la representación previa del componente, pero es una medida extrema que se debe tomar en muchos casos que no cumplan las especificaciones del componente.
Hay tres enfoques que puede adoptar para abordar este escenario. Se presentan a continuación, del más al menos recomendado:
Recomendado para servicios de marco compartidos: para los servicios de marco compartidos que simplemente no están registrados en el lado del servidor en el proyecto principal, registra los servicios en el proyecto principal, lo que hace que estén disponibles durante la representación previa. Para obtener un ejemplo de este escenario, consulta las instrucciones para los servicios de HttpClient en Llamada a una API web desde una aplicación de ASP.NET Core Blazor.
Recomendado para servicios fuera del marco compartido: crea una implementación de servicio personalizada para el servicio en el servidor. Normalmente, usa el servicio en componentes interactivos del proyecto
.Client
. Para obtener una demostración de este enfoque, consulta los entornosBlazor de ASP.NET Core.Crea una abstracción de servicio y crea implementaciones para el servicio en los proyectos de servidor y
.Client
. Registra los servicios en cada proyecto. Inserta el servicio personalizado en el componente.Es posible que puedas agregar una referencia de paquete de proyecto
.Client
a un paquete del lado servidor y revertir al uso de la API del lado servidor al realizar la representación previa en el servidor.
Detección de componentes de ensamblados adicionales
Los ensamblados adicionales deben revelarse al marco de Blazor para detectar componentes de Razor enrutables en proyectos a los que se hace referencia. Para obtener más información, consulta Enrutamiento y navegación de Blazor de ASP.NET Core.
Cierre de circuitos cuando no haya componentes del servidor interactivo restantes
Los componentes del Servidor interactivo controlan los eventos de la interfaz de usuario web mediante una conexión en tiempo real con el explorador denominado circuito. Un circuito y su estado asociado se crean cuando se representa un componente de Servidor interactivo raíz. El circuito se cierra cuando no quedan componentes de Servidor interactivo en la página, lo que libera los recursos del servidor.
Modos de representación abreviados personalizados
La directiva @rendermode
toma un único parámetro que es una instancia estática de tipo IComponentRenderMode. El atributo de directiva @rendermode
puede tomar cualquier instancia del modo de representación, estática o no. El marco de Blazor proporciona la clase estática RenderMode con algunos modos de representación predefinidos para mayor comodidad, pero puede crear los suyos propios.
Normalmente, un componente usa la siguiente directiva @rendermode
para deshabilitar la representación previa:
@rendermode @(new InteractiveServerRenderMode(prerender: false))
Sin embargo, considera el ejemplo siguiente que crea un modo de representación interactivo del lado servidor abreviado sin representación previa mediante el archivo _Imports
de la aplicación (Components/_Imports.razor
):
public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } =
new InteractiveServerRenderMode(prerender: false);
Usa el modo de representación abreviado en componentes en toda la carpeta Components
:
@rendermode InteractiveServerWithoutPrerendering
Como alternativa, una única instancia de componente puede definir un modo de representación personalizado mediante un campo privado:
@rendermode interactiveServerWithoutPrerendering
...
@code {
private static IComponentRenderMode interactiveServerWithoutPrerendering =
new InteractiveServerRenderMode(prerender: false);
}
Por el momento, el enfoque del modo de representación abreviado probablemente solo sea útil para reducir el nivel de detalle de especificar la marca prerender
. El enfoque abreviado podría ser más útil en el futuro si se dispone de marcas adicionales para la representación interactiva y se desea crear modos de representación abreviados con diferentes combinaciones de marcas.
Inserción de servicios a través de un archivo de importación de nivel superior (_Imports.razor
)
Esta sección solo se aplica a Blazor Web App.
Un archivo de importación de nivel superior en la carpeta Components
(Components/_Imports.razor
) inserta sus referencias en todos los componentes de la jerarquía de carpetas, que incluye el componente App
(App.razor
). El componente App
siempre se representa estáticamente incluso si la representación previa de un componente de página está deshabilitado. Por lo tanto, la inserción de servicios a través del archivo de importación de nivel superior da como resultado la resolución de dos instancias del servicio en los componentes de página.
Para solucionar este escenario, inserta el servicio en un nuevo archivo de importaciones colocado en la carpeta Pages
(Components/Pages/_Imports.razor
). Desde esa ubicación, el servicio solo se resuelve una vez en los componentes de la página.
Recursos adicionales
- Compresión de WebSocket
- ASP.NET Core Blazor JavaScript con representación estática del lado servidor (SSR estática)
- Valores/parámetros en cascada y límites del modo de representación: consulte también la sección Parámetros en cascada a nivel raíz anteriormente en este artículo.
- Bibliotecas de clases de ASP.NET Core (RCL) Razor con representación estática del lado servidor (SSR estático)
- ASP.NET Core Blazor JavaScript con representación estática del lado servidor (SSR estática)
- Valores/parámetros en cascada y límites del modo de representación: consulte también la sección Parámetros en cascada a nivel raíz anteriormente en este artículo.
- Bibliotecas de clases de ASP.NET Core (RCL) Razor con representación estática del lado servidor (SSR estático)