Integración y representación previa de componentes Razor de ASP.NET Core

Los componentes Razor se pueden integrar en aplicaciones de Razor Pages y MVC en una solución Blazor WebAssembly hospedada. Cuando se representa la página o la vista, los componentes se pueden representar previamente al mismo tiempo.

Configuración de la solución

Configuración de la representación previa

Para configurar la representación previa de una aplicación Blazor WebAssembly hospedada:

  1. Hospede la aplicación Blazor WebAssembly en una aplicación ASP.NET Core. Se puede agregar una aplicación Blazor WebAssembly independiente a una solución de ASP.NET Core, o bien se puede usar una aplicación Blazor WebAssembly hospedada creada a partir de la plantilla de proyecto de Blazor WebAssembly con la opción hospedada:

    • Visual Studio: active la casilla ASP.NET Core hospedado del cuadro de diálogo Información adicional al crear la aplicación Blazor WebAssembly. En los ejemplos de este artículo, la solución se llama BlazorHosted.
    • Shell de comandos de la CLI de Visual Studio Code/:NET: dotnet new blazorwasm -ho (use la opción -ho|--hosted). Use la opción -o|--output {LOCATION} para crear una carpeta para la solución y establecer los espacios de nombres del proyecto de la solución. En los ejemplos de este artículo, la solución se llama BlazorHosted ( dotnet new blazorwasm -ho -o BlazorHosted).

    En los ejemplos de este artículo, el espacio de nombres del proyecto de cliente es BlazorHosted.Client y el espacio de nombres del proyecto de servidor es BlazorHosted.Server.

  2. Elimine el archivo wwwroot/index.html del proyecto Client de Blazor WebAssembly.

  3. En el proyecto Client , elimine las líneas siguientes en Program.cs:

    - builder.RootComponents.Add<App>("#app");
    - builder.RootComponents.Add<HeadOutlet>("head::after");
    
  4. Agregue archivos _Host.cshtml y _Layout.cshtml a la carpeta Pages del proyecto Server . Puede obtener los archivos de un proyecto creado a partir de la plantilla de Blazor Server mediante Visual Studio o la CLI de .NET con el comando dotnet new blazorserver -o BlazorServer en un shell de comandos (la opción -o BlazorServer crea una carpeta para el proyecto). Después de colocar los archivos en la carpeta Pages del proyecto Server :

    Realice los cambios siguientes en el archivo _Layout.cshtml:

    • Actualice el espacio de nombres Pages en la parte superior del archivo para que coincida con el espacio de nombres de las páginas de la aplicación Server . El marcador de posición {APP NAMESPACE} del ejemplo siguiente representa el espacio de nombres de las páginas de la aplicación de donantes que proporcionó el archivo _Layout.cshtml:

      Eliminar:

      - @namespace {APP NAMESPACE}.Pages
      

      Agregue:

      @namespace BlazorHosted.Server.Pages
      
    • Agregue una directiva @using para el proyecto Client en la parte superior del archivo:

      @using BlazorHosted.Client
      
    • Actualice los vínculos de la hoja de estilos para que apunten a las hojas de estilos del proyecto de WebAssembly. En el ejemplo siguiente, el espacio de nombres del proyecto de cliente es BlazorHosted.Client. El marcador de posición {APP NAMESPACE} representa el espacio de nombres de la aplicación de donantes que proporcionó el archivo _Layout.cshtml. Actualice el asistente de etiquetas de componentes (etiqueta <component>) para el componente HeadOutlet para representar previamente el componente.

      Eliminar:

      - <link href="css/site.css" rel="stylesheet" />
      - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" />
      - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
      

      Agregue:

      <link href="css/app.css" rel="stylesheet" />
      <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
      <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
      

      Nota

      Deje como está el elemento <link> que solicita la hoja de estilos de arranque css/bootstrap/bootstrap.min.css.

    • Actualice el origen del script de Blazor para usar el script de Blazor WebAssembly del lado cliente:

      Eliminar:

      - <script src="_framework/blazor.server.js"></script>
      

      Agregue:

      <script src="_framework/blazor.webassembly.js"></script>
      

    En el archivo _Host.cshtml:

    • Cambie el espacio de nombres Pages por el del proyecto Client . El marcador de posición {APP NAMESPACE} representa el espacio de nombres de las páginas de la aplicación de donantes que proporcionó el archivo _Host.cshtml:

      Eliminar:

      - @namespace {APP NAMESPACE}.Pages
      

      Agregue:

      @namespace BlazorHosted.Client
      
    • Actualice el objeto render-mode del asistente de etiquetas de componentes para representar previamente el componente App raíz con WebAssemblyPrerendered:

      Eliminar:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      

      Agregue:

      <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      
  5. En la asignación de puntos de conexión del proyecto Server de Program.cs, cambie la reserva del archivo index.html por la página _Host.cshtml:

    Eliminar:

    - app.MapFallbackToFile("index.html");
    

    Agregue:

    app.MapFallbackToPage("/_Host");
    
  6. Ejecute el proyecto Server . La aplicación Blazor WebAssembly hospedada se representa previamente en el proyecto Server para los clientes.

Configuración para insertar componentes Razor en páginas y vistas

En las secciones y ejemplos siguientes para insertar componentes Razor de la aplicación Blazor WebAssembly de Client en páginas y vistas de la aplicación de servidor se necesita configuración adicional.

El proyecto Server debe tener los siguientes archivos y carpetas.

Razor Pages:

  • Pages/Shared/_Layout.cshtml
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml

MVC:

  • Views/Shared/_Layout.cshtml
  • Views/_ViewImports.cshtml
  • Views/_ViewStart.cshtml

Los archivos anteriores se pueden obtener generando una aplicación a partir de las plantillas de proyecto de ASP.NET Core mediante:

  • Herramientas de creación de proyectos de Visual Studio.
  • Apertura de un shell de comandos y ejecución de dotnet new razor -o {APP NAME} (Razor Pages) o dotnet new mvc -o {APP NAME} (MVC). La opción -o|--output con un valor del marcador de posición {APP NAME} proporciona un nombre para la aplicación y crea una carpeta para la aplicación.

Actualice los espacios de nombres del archivo _ViewImports.cshtml importado para que coincidan con los que utiliza el proyecto Server que recibe los archivos.

Pages/_ViewImports.cshtml (Razor Pages):

@using BlazorHosted.Server
@namespace BlazorHosted.Server.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Views/_ViewImports.cshtml (MVC):

@using BlazorHosted.Server
@using BlazorHosted.Server.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Actualice el archivo de diseño importado (_Layout.cshtml) para incluir los estilos del proyecto Client . En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client. El elemento <title> se puede actualizar al mismo tiempo. El marcador de posición {APP NAME} representa el nombre de la aplicación del proyecto de donantes.

Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-   <title>@ViewData["Title"] - {APP NAME}</title>
+   <title>@ViewData["Title"] - BlazorHosted</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
+   <link href="css/app.css" rel="stylesheet" />
+   <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>

El diseño importado contiene los vínculos de navegación Home y Privacy. Para que el vínculo Home apunte a la aplicación Blazor WebAssembly hospedada, cambie el hipervínculo:

- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

En un archivo de diseño de MVC:

- <a class="nav-link text-dark" asp-area="" asp-controller="Home" 
-     asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

Para que el vínculo Privacy dirija a una página de privacidad (Razor Pages), agregue una página de privacidad al proyecto Server .

Pages/Privacy.cshtml en el proyecto Server :

@page
@model PrivacyModel
@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

Para una vista de privacidad basada en MVC, cree una vista de privacidad en el proyecto Server .

View/Home/Privacy.cshtml en el proyecto Server :

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>

En el controlador Home de la aplicación MVC, devuelva la vista.

Agrega el código siguiente a Controllers/HomeController.cs:

public IActionResult Privacy()
{
    return View();
}

Si importa archivos desde una aplicación de donantes, asegúrese de actualizar los espacios de nombres de los archivos para que coincidan con el del proyecto Server (por ejemplo, BlazorHosted.Server).

Importe los recursos estáticos al proyecto Server desde la carpeta wwwroot del proyecto de donantes:

  • Carpeta wwwroot/css y su contenido
  • Carpeta wwwroot/js y su contenido
  • Carpeta wwwroot/lib y su contenido

Si el proyecto de donantes se crea a partir de una plantilla de proyecto de ASP.NET Core y los archivos no están modificados, puede copiar toda la carpeta wwwroot de dicho proyecto en el proyecto Server y quitar el archivo de icono favicon.ico.

Advertencia

Evite colocar el mismo archivo (por ejemplo, favicon.ico) en las carpetas wwwroot de Client y Server . Si está presente el mismo archivo en ambas carpetas, se produce una excepción porque el recurso estático de cada carpeta comparte la misma ruta de acceso raíz web:

El recurso web estático "...\favicon.ico" tiene una ruta de acceso raíz web en conflicto "/wwwroot/favicon.ico" con el archivo de proyecto "wwwroot\favicon.ico".

Por lo tanto, hospede un recurso estático en una de las carpetas wwwroot, no en ambas.

Después de adoptar la configuración anterior, inserte componentes Razor en páginas o vistas del proyecto Server . Use las instrucciones de las secciones siguientes de este artículo:

  • Representación de componentes en una página o vista con la aplicación auxiliar de etiquetas de componentes
  • Representación de componentes en una página o vista con un selector de CSS

Representación de componentes en una página o vista con la aplicación auxiliar de etiquetas de componentes

Después de configurar la solución, incluida la configuración adicional, el asistente de etiquetas de componentes admite dos modos de representación para representar un componente de una aplicación Blazor WebAssembly en una página o vista:

En el siguiente ejemplo de Razor Pages, el componente Counter se representa en una página. Para convertir el componente en interactivo, el script Blazor WebAssembly se incluye en la sección de representación de la página. Para evitar el uso del espacio de nombres completo del componente Counter con el asistente de etiquetas de componentes ({APP ASSEMBLY}.Pages.Counter), agregue una directiva @using para el espacio de nombres Pages del proyecto de cliente. En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client.

En el proyecto Server , Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Ejecute el proyecto Server . Vaya a la página Razor en /razorpagescounter1. El componente Counter representado previamente se inserta en la página.

RenderMode configura si el componente:

  • Se representa previamente en la página.
  • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

Puede ser necesario realizar trabajo adicional en función de los recursos estáticos que usan los componentes y de cómo se organizan las páginas de diseño en una aplicación. Normalmente, los scripts se agregan a la sección de representación de Scripts de una vista o una página, y las hojas de estilos se agregan al contenido del elemento <head> del diseño.

Representación de componentes en una página o vista con un selector de CSS

Después de configurar la solución, incluida la configuración adicional, agregue los componentes raíz al proyecto Client de una solución Blazor WebAssembly hospedada en el archivo Program.cs. En el siguiente ejemplo, el componente Counter se declara como un componente raíz con un selector de CSS que selecciona el elemento con el objeto id que coincide con counter-component. En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client.

En el archivo Program.cs del proyecto Client , agregue el espacio de nombres de los componentes Razor del proyecto en la parte superior del archivo:

using BlazorHosted.Client.Pages;

Después de establecer el elemento builder en Program.cs, agregue el componente Counter como componente raíz:

builder.RootComponents.Add<Counter>("#counter-component");

En el siguiente ejemplo de Razor Pages, el componente Counter se representa en una página. Para convertir el componente en interactivo, el script Blazor WebAssembly se incluye en la sección de representación de la página.

En el proyecto Server , Pages/RazorPagesCounter2.cshtml:

@page

<div id="counter-component">Loading...</div>

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Ejecute el proyecto Server . Vaya a la página Razor en /razorpagescounter2. El componente Counter representado previamente se inserta en la página.

Puede ser necesario realizar trabajo adicional en función de los recursos estáticos que usan los componentes y de cómo se organizan las páginas de diseño en una aplicación. Normalmente, los scripts se agregan a la sección de representación de Scripts de una vista o una página, y las hojas de estilos se agregan al contenido del elemento <head> del diseño.

Nota

En el ejemplo anterior se produce una excepción JSException si una aplicación Blazor WebAssembly se representa previamente y se integra en una Razoraplicación Pages o MVC a la vez con el uso de un selector de CSS. Al navegar a uno de los componentes Razor del proyecto Client o a una página o vista de Server con un componente insertado, se producen una o varias excepciones JSException.

Este comportamiento es normal porque la representación previa y la integración de una aplicación Blazor WebAssembly con componentes de Razor enrutables no son compatibles con el uso de selectores de CSS.

Si ha estado trabajando con los ejemplos de las secciones anteriores y solo desea ver que el selector de CSS funciona en la aplicación de ejemplo, convierta en comentario la especificación del componente raíz App del archivo Program.cs del proyecto Client :

- builder.RootComponents.Add<App>("#app");
+ //builder.RootComponents.Add<App>("#app");

Vaya a la página o vista con el componente Razor insertado que usa un selector de CSS (por ejemplo, /razorpagescounter2 del ejemplo anterior). La página o vista se carga con el componente insertado y el componente insertado funciona según lo previsto.

Los componentes Razor se pueden integrar en aplicaciones de Razor Pages y MVC en una aplicación Blazor Server. Cuando se representa la página o la vista, los componentes se pueden representar previamente al mismo tiempo.

Después de configurar el proyecto, use la guía que aparece en las secciones siguientes en función de los requisitos del proyecto:

Configuración

Una aplicación Razor Pages o MVC existente puede integrar componentes Razor en páginas y vistas:

  1. En el archivo de diseño del proyecto:

    • Agregue la siguiente etiqueta <base> al elemento <head> en Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

      <base href="~/" />
      

      El valor href (la ruta de acceso base de la aplicación) del ejemplo anterior da por hecho que la aplicación reside en la ruta de acceso URL raíz (/). Si la aplicación es una subaplicación, siga las instrucciones de la sección Ruta de acceso base de la aplicación del artículo Hospedaje e implementación de ASP.NET Core Blazor.

    • Agregue una etiqueta <script> para el script blazor.server.js inmediatamente antes de la sección de representación Scripts (@await RenderSectionAsync(...)) en el diseño de la aplicación.

      Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

      <script src="_framework/blazor.server.js"></script>
      

      El marco agrega el script blazor.server.js a la aplicación. No es necesario agregar manualmente un archivo de script blazor.server.js a la aplicación.

  2. Agregue un archivo imports a la carpeta raíz del proyecto con el contenido siguiente. Cambie el marcador de posición {APP NAMESPACE} al espacio de nombres del proyecto.

    _Imports.razor:

    @using System.Net.Http
    @using Microsoft.AspNetCore.Authorization
    @using Microsoft.AspNetCore.Components.Authorization
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.AspNetCore.Components.Web.Virtualization
    @using Microsoft.JSInterop
    @using {APP NAMESPACE}
    
  3. Registre los servicios Blazor Server en Program.cs, donde se registran los servicios:

    builder.Services.AddServerSideBlazor();
    
  4. Agregue el punto de conexión Blazor Hub a los puntos de conexión de Program.cs donde se asignan las rutas.

    Coloque la siguiente línea después de la llamada a MapRazorPages ( Razor Pages) o MapControllerRoute (MVC):

    app.MapBlazorHub();
    
  5. Integre los componentes en cualquier página o vista. Por ejemplo, agregue un componente Counter a la carpeta Shared del proyecto.

    Pages/Shared/Counter.razor (Razor Pages) o Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages:

    En la página Index del proyecto de una aplicación Razor Pages, agregue el espacio de nombres del componente Counter e inserte el componente en la página. Cuando se carga la página Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Pages/Index.cshtml:

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

    MVC:

    En la vista Index del proyecto de una aplicación MVC, agregue el espacio de nombres del componente Counter e inserte el componente en la vista. Cuando se carga la vista Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Views/Home/Index.cshtml:

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    

Para obtener más información, vea la sección Representación de componentes a partir de una página o vista.

Uso de componentes enrutables en una aplicación Razor Pages

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones Razor Pages:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. Agregue una página _Host al proyecto con el contenido siguiente.

    Pages/_Host.cshtml:

    @page "/blazor"
    @namespace {APP NAMESPACE}.Pages.Shared
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @{
        Layout = "_Layout";
    }
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    En este escenario, los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. En los puntos de conexión Program.cs, agregue una ruta de prioridad baja para la página _Host como último punto de conexión:

    app.MapFallbackToPage("/_Host");
    
  5. Agregue componentes enrutables al proyecto. El ejemplo siguiente es un componente RoutableCounter basado en el componente Counter de las plantillas de proyecto de Blazor.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Uso de componentes enrutables en una aplicación MVC

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones MVC, haga lo siguiente:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <p role="alert">Sorry, there's nothing at this address.</p>
        </NotFound>
    </Router>
    
  3. Agregue una vista _Host al proyecto con el contenido siguiente.

    Views/Home/_Host.cshtml:

    @namespace {APP NAMESPACE}.Views.Shared
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @{
        Layout = "_Layout";
    }
    
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    

    Los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. Agregue una acción al controlador Home.

    Controllers/HomeController.cs:

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. En los puntos de conexión Program.cs, agregue una ruta de prioridad baja para la acción del controlador que devuelva la vista _Host:

    app.MapFallbackToController("Blazor", "Home");
    
  6. Cree una carpeta Pages en la aplicación MVC y agregue componentes enrutables. El ejemplo siguiente es un componente RoutableCounter basado en el componente Counter de las plantillas de proyecto de Blazor.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Representación de componentes a partir de una página o vista

Esta sección pertenece a la adición de componentes a páginas o vistas, donde los componentes no son enrutables directamente desde las solicitudes del usuario.

Para representar un componente a partir de una página o vista, use el asistente de etiquetas de componente.

Representación de componentes interactivos con estado

Los componentes interactivos con estado se pueden agregar a una página de Razor o una vista.

Cuando se representa la página o la vista:

  • El componente se representa previamente con la página o la vista.
  • Se pierde el estado inicial del componente que se usa para la representación previa.
  • Cuando se establece la conexión SignalR, se crea un estado del componente.

La siguiente página de Razor representa un componente Counter:

<h1>My Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Representación de componentes no interactivos

En la siguiente página de Razor, el componente Counter se representa de forma estática con un valor inicial que se especifica mediante un formulario. Como el componente se representa de forma estática, no es interactivo:

<h1>My Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Espacios de nombres de componentes

Si usa una carpeta personalizada para contener los componentes _ViewImports.cshtml del proyecto, agregue el espacio de nombres que representa la carpeta a la página o vista, o bien al archivo Razor. En el ejemplo siguiente:

  • Los componentes se almacenan en la carpeta Components del proyecto.
  • El marcador de posición {APP NAMESPACE} es el espacio de nombres del proyecto. Components representa el nombre de la carpeta.
@using {APP NAMESPACE}.Components

El archivo _ViewImports.cshtml se encuentra en la carpeta Pages de una aplicación Razor Pages o en la carpeta Views de una aplicación de MVC.

Para obtener más información, vea Componentes de Razor de ASP.NET Core.

Conservación del estado representado previamente

Si no se conserva el estado representado previamente, se pierde el estado usado durante la representación previa, por lo que este se debe volver a crear una vez que la aplicación se haya cargado por completo. Si algún estado se configura de forma asincrónica, puede que la interfaz de usuario representada previamente parpadee mientras se sustituye por marcadores de posición temporales y se vuelve a representar.

Para solucionar estos problemas, Blazor admite el estado persistente en una página representada previamente mediante el Asistente para la conservación de etiquetas de estado de componente (<preserve-component-state />). Agregue la etiqueta <preserve-component-state /> dentro de la etiqueta de cierre </body>.

Pages/_Layout.cshtml:

<body>
    ...

    <persist-component-state />
</body>

En la aplicación, decida qué estado quiere conservar mediante el servicio PersistentComponentState. El evento PersistentComponentState.RegisterOnPersisting se desencadena justo antes de que el estado se conserve en la página representada previamente, lo que permite a un componente recuperar el estado durante su inicialización.

En el ejemplo siguiente se muestra cómo se conserva la previsión meteorológica del componente FetchData desde una aplicación Blazor WebAssembly hospedada basada en la plantilla de proyecto Blazor durante la representación previa y, después, se recupera para inicializar el componente. El Asistente para la conservación de etiquetas de estado de componente conserva el estado del componente después de todas las invocaciones de componentes.

Pages/FetchData.razor:

@page "/fetchdata"
@implements IDisposable
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
    private PersistingComponentStateSubscription _persistingSubscription;

    protected override async Task OnInitializedAsync()
    {
        _persistingSubscription = ApplicationState.RegisterOnPersisting(PersistForecasts);

        if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>("fetchdata", out var restored))
        {
            forecasts = await WeatherForecastService.GetForecastAsync(DateTime.Now);
        }
        else
        {
            forecasts = restored!;
        }
    }

    private Task PersistForecasts()
    {
        ApplicationState.PersistAsJson("fetchdata", forecasts);

        return Task.CompletedTask;
    }

    void IDisposable.Dispose()
    {
        _persistingSubscription.Dispose();
    }
}

Al inicializar componentes con el mismo estado que se usa durante la representación previa, los pasos de inicialización costosos solo se ejecutan una vez. La interfaz de usuario representada también coincide con la que se ha representado previamente, por lo que no se produce ningún parpadeo en el explorador.

Recursos de Blazor WebAssembly adicionales

Los componentes Razor se pueden integrar en aplicaciones de Razor Pages y MVC en una solución Blazor WebAssembly hospedada. Cuando se representa la página o la vista, los componentes se pueden representar previamente al mismo tiempo.

Configuración de la solución

Configuración de la representación previa

Para configurar la representación previa de una aplicación Blazor WebAssembly hospedada:

  1. Hospede la aplicación Blazor WebAssembly en una aplicación ASP.NET Core. Se puede agregar una aplicación Blazor WebAssembly independiente a una solución de ASP.NET Core, o bien se puede usar una aplicación Blazor WebAssembly hospedada creada a partir de la plantilla de proyecto de Blazor WebAssembly con la opción hospedada:

    • Visual Studio: active la casilla ASP.NET Core hospedado del cuadro de diálogo Información adicional al crear la aplicación Blazor WebAssembly. En los ejemplos de este artículo, la solución se llama BlazorHosted.
    • Shell de comandos de la CLI de Visual Studio Code/:NET: dotnet new blazorwasm -ho (use la opción -ho|--hosted). Use la opción -o|--output {LOCATION} para crear una carpeta para la solución y establecer los espacios de nombres del proyecto de la solución. En los ejemplos de este artículo, la solución se llama BlazorHosted ( dotnet new blazorwasm -ho -o BlazorHosted).

    En los ejemplos de este artículo, el espacio de nombres del proyecto de cliente es BlazorHosted.Client y el espacio de nombres del proyecto de servidor es BlazorHosted.Server.

  2. Elimine el archivo wwwroot/index.html del proyecto Client de Blazor WebAssembly.

  3. En el proyecto Client , elimine la línea siguiente en Program.cs:

    - builder.RootComponents.Add<App>("#app");
    
  4. Agregue un archivo Pages/_Host.cshtml a la carpeta Pages del proyecto Server . Puede obtener un archivo _Host.cshtml de un proyecto creado a partir de la plantilla de Blazor Server con el comando dotnet new blazorserver -o BlazorServer de un shell de comandos (la opción -o BlazorServer crea una carpeta para el proyecto). Después de colocar el archivo Pages/_Host.cshtml en el proyecto Server de la solución Blazor WebAssembly hospedada, realice en él los siguientes cambios:

    • Proporcione una directiva @using para el proyecto Client (por ejemplo, @using BlazorHosted.Client).

    • Actualice los vínculos de la hoja de estilos para que apunten a las hojas de estilos del proyecto de WebAssembly. En el ejemplo siguiente, el espacio de nombres del proyecto de cliente es BlazorHosted.Client:

      - <link href="css/site.css" rel="stylesheet" />
      - <link href="_content/BlazorServer/_framework/scoped.styles.css" rel="stylesheet" />
      + <link href="css/app.css" rel="stylesheet" />
      + <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
      

      Nota

      Deje como está el elemento <link> que solicita la hoja de estilos de arranque css/bootstrap/bootstrap.min.css.

    • Actualice el objeto render-mode del asistente de etiquetas de componentes para representar previamente el componente App raíz con WebAssemblyPrerendered:

      - <component type="typeof(App)" render-mode="ServerPrerendered" />
      + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
      
    • Actualice el origen del script de Blazor para usar el script de Blazor WebAssembly del lado cliente:

      - <script src="_framework/blazor.server.js"></script>
      + <script src="_framework/blazor.webassembly.js"></script>
      
  5. En el objeto Startup.Configure del proyecto Server , cambie la reserva del archivo index.html a la página _Host.cshtml.

    Startup.cs:

    - endpoints.MapFallbackToFile("index.html");
    + endpoints.MapFallbackToPage("/_Host");
    
  6. Ejecute el proyecto Server . La aplicación Blazor WebAssembly hospedada se representa previamente en el proyecto Server para los clientes.

Configuración para insertar componentes Razor en páginas y vistas

En las secciones y ejemplos siguientes de este artículo para insertar componentes Razor de la aplicación cliente Blazor WebAssembly en páginas y vistas de la aplicación de servidor se necesita configuración adicional.

Use un archivo de diseño de Razor Pages o MVC en el proyecto Server . El proyecto Server debe tener los siguientes archivos y carpetas.

Razor Pages:

  • Pages/Shared/_Layout.cshtml
  • Pages/_ViewImports.cshtml
  • Pages/_ViewStart.cshtml

MVC:

  • Views/Shared/_Layout.cshtml
  • Views/_ViewImports.cshtml
  • Views/_ViewStart.cshtml

Obtenga los archivos anteriores de una aplicación creada a partir de la plantilla de proyecto de Razor Pages o MVC. Para obtener más información, vea Tutorial: Introducción a Razor Pages en ASP.NET Core o Introducción a ASP.NET Core MVC.

Actualice los espacios de nombres del archivo _ViewImports.cshtml importado para que coincidan con los que utiliza el proyecto Server que recibe los archivos.

Actualice el archivo de diseño importado (_Layout.cshtml) para incluir los estilos del proyecto Client . En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client. El elemento <title> se puede actualizar al mismo tiempo.

Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-   <title>@ViewData["Title"] - DonorProject</title>
+   <title>@ViewData["Title"] - BlazorHosted</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
+   <link href="css/app.css" rel="stylesheet" />
+   <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>

El diseño importado contiene los vínculos de navegación Home y Privacy. Para que el vínculo Home apunte a la aplicación Blazor WebAssembly hospedada, cambie el hipervínculo:

- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

En un archivo de diseño de MVC:

- <a class="nav-link text-dark" asp-area="" asp-controller="Home" 
-     asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>

Para que el vínculo Privacy dirija a una página de privacidad, agregue una página de privacidad al proyecto Server .

Pages/Privacy.cshtml en el proyecto Server :

@page
@model BlazorHosted.Server.Pages.PrivacyModel
@{
}

<h1>Privacy Policy</h1>

Si se prefiere una vista de privacidad basada en MVC, cree una vista de privacidad en el proyecto Server .

View/Home/Privacy.cshtml:

@{
    ViewData["Title"] = "Privacy Policy";
}

<h1>@ViewData["Title"]</h1>

En el controlador Home, devuelva la vista.

Controllers/HomeController.cs:

+ public IActionResult Privacy()
+ {
+     return View();
+ }

Importe los recursos estáticos al proyecto Server desde la carpeta wwwroot del proyecto de donantes:

  • Carpeta wwwroot/css y su contenido
  • Carpeta wwwroot/js y su contenido
  • Carpeta wwwroot/lib y su contenido

Si el proyecto de donantes se crea a partir de una plantilla de proyecto de ASP.NET Core y los archivos no están modificados, puede copiar toda la carpeta wwwroot de dicho proyecto en el proyecto Server y quitar el archivo de icono favicon.ico.

Nota

Si los proyectos Client y Server contienen el mismo recurso estático en sus carpetas wwwroot (por ejemplo, favicon.ico), se produce una excepción porque el recurso estático de cada carpeta comparte la misma ruta de acceso raíz web:

El recurso web estático "...\favicon.ico" tiene una ruta de acceso raíz web en conflicto "/wwwroot/favicon.ico" con el archivo de proyecto "wwwroot\favicon.ico".

Por lo tanto, hospede un recurso estático en una de las carpetas wwwroot, no en ambas.

Representación de componentes en una página o vista con la aplicación auxiliar de etiquetas de componentes

Después de configurar la solución, incluida la configuración adicional, el asistente de etiquetas de componentes admite dos modos de representación para representar un componente de una aplicación Blazor WebAssembly en una página o vista:

En el siguiente ejemplo de Razor Pages, el componente Counter se representa en una página. Para convertir el componente en interactivo, el script Blazor WebAssembly se incluye en la sección de representación de la página. Para evitar el uso del espacio de nombres completo del componente Counter con el asistente de etiquetas de componentes ({APP ASSEMBLY}.Pages.Counter), agregue una directiva @using para el espacio de nombres Pages del proyecto de cliente. En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client.

En el proyecto Server , Pages/RazorPagesCounter1.cshtml:

@page
@using BlazorHosted.Client.Pages

<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Ejecute el proyecto Server . Vaya a la página Razor en /razorpagescounter1. El componente Counter representado previamente se inserta en la página.

RenderMode configura si el componente:

  • Se representa previamente en la página.
  • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

Puede ser necesario realizar trabajo adicional en función de los recursos estáticos que usan los componentes y de cómo se organizan las páginas de diseño en una aplicación. Normalmente, los scripts se agregan a la sección de representación de Scripts de una vista o una página, y las hojas de estilos se agregan al contenido del elemento <head> del diseño.

Representación de componentes en una página o vista con un selector de CSS

Después de configurar la solución, incluida la configuración adicional, agregue los componentes raíz al proyecto Client de una solución Blazor WebAssembly hospedada en Program.cs. En el siguiente ejemplo, el componente Counter se declara como un componente raíz con un selector de CSS que selecciona el elemento con el objeto id que coincide con counter-component. En el ejemplo siguiente, el espacio de nombres del proyecto Client es BlazorHosted.Client.

En el archivo Program.cs del proyecto Client , agregue el espacio de nombres de los componentes Razor del proyecto en la parte superior del archivo:

+ using BlazorHosted.Client.Pages;

Después de establecer el elemento builder en Program.cs, agregue el componente Counter como componente raíz:

+ builder.RootComponents.Add<Counter>("#counter-component");

En el siguiente ejemplo de Razor Pages, el componente Counter se representa en una página. Para convertir el componente en interactivo, el script Blazor WebAssembly se incluye en la sección de representación de la página.

En el proyecto Server , Pages/RazorPagesCounter2.cshtml:

@page

<div id="counter-component">Loading...</div>

@section Scripts {
    <script src="_framework/blazor.webassembly.js"></script>
}

Ejecute el proyecto Server . Vaya a la página Razor en /razorpagescounter2. El componente Counter representado previamente se inserta en la página.

Puede ser necesario realizar trabajo adicional en función de los recursos estáticos que usan los componentes y de cómo se organizan las páginas de diseño en una aplicación. Normalmente, los scripts se agregan a la sección de representación de Scripts de una vista o una página, y las hojas de estilos se agregan al contenido del elemento <head> del diseño.

Nota

En el ejemplo anterior se produce una excepción JSException si una aplicación Blazor WebAssembly se representa previamente y se integra en una aplicación Razor Pages o MVC a la vez con un selector de CSS. Al desplazarse a uno de los componentes Razor del proyecto Client se produce la siguiente excepción:

Microsoft.JSInterop.JSException: Could not find any element matching selector '#counter-component' (No se ha podido encontrar ningún elemento que coincida con el selector "#counter-component").

Este comportamiento es normal porque la representación previa y la integración de una aplicación Blazor WebAssembly con componentes de Razor enrutables no son compatibles con el uso de selectores de CSS.

Los componentes Razor se pueden integrar en aplicaciones de Razor Pages y MVC en una aplicación Blazor Server. Cuando se representa la página o la vista, los componentes se pueden representar previamente al mismo tiempo.

Después de configurar el proyecto, use la guía que aparece en las secciones siguientes en función de los requisitos del proyecto:

Configuración

Una aplicación Razor Pages o MVC existente puede integrar componentes Razor en páginas y vistas:

  1. En el archivo de diseño del proyecto:

    • Agregue la siguiente etiqueta <base> al elemento <head> en Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

      + <base href="~/" />
      

      El valor href (la ruta de acceso base de la aplicación) del ejemplo anterior da por hecho que la aplicación reside en la ruta de acceso URL raíz (/). Si la aplicación es una subaplicación, siga las instrucciones de la sección Ruta de acceso base de la aplicación del artículo Hospedaje e implementación de ASP.NET Core Blazor.

    • Agregue una etiqueta <script> para el script blazor.server.js inmediatamente antes de la sección de representación Scripts.

      Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

          ...
      +   <script src="_framework/blazor.server.js"></script>
      
          @await RenderSectionAsync("Scripts", required: false)
      </body>
      

      El marco agrega el script blazor.server.js a la aplicación. No es necesario agregar manualmente un archivo de script blazor.server.js a la aplicación.

  2. Agregue un archivo imports a la carpeta raíz del proyecto con el contenido siguiente. Cambie el marcador de posición {APP NAMESPACE} al espacio de nombres del proyecto.

    _Imports.razor:

    @using System.Net.Http
    @using Microsoft.AspNetCore.Authorization
    @using Microsoft.AspNetCore.Components.Authorization
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.JSInterop
    @using {APP NAMESPACE}
    
  3. Registre el servicio Blazor Server en Startup.ConfigureServices.

    Startup.cs:

    + services.AddServerSideBlazor();
    
  4. Agregue el punto de conexión Blazor Hub a los puntos de conexión (app.UseEndpoints) de Startup.Configure.

    Startup.cs:

    + endpoints.MapBlazorHub();
    
  5. Integre los componentes en cualquier página o vista. Por ejemplo, agregue un componente Counter a la carpeta Shared del proyecto.

    Pages/Shared/Counter.razor (Razor Pages) o Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages:

    En la página Index del proyecto de una aplicación Razor Pages, agregue el espacio de nombres del componente Counter e inserte el componente en la página. Cuando se carga la página Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Pages/Index.cshtml:

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

    En el ejemplo anterior, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres de la aplicación.

    MVC:

    En la vista Index del proyecto de una aplicación MVC, agregue el espacio de nombres del componente Counter e inserte el componente en la vista. Cuando se carga la vista Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Views/Home/Index.cshtml:

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

Para obtener más información, vea la sección Representación de componentes a partir de una página o vista.

Uso de componentes enrutables en una aplicación Razor Pages

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones Razor Pages:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    

    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, consulte Migración de ASP.NET Core 3.1 a 5.0.

  3. Agregue una página _Host al proyecto con el contenido siguiente.

    Pages/_Host.cshtml:

    @page "/blazor"
    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    Los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. En los puntos de conexión Startup.Configure de Startup.cs, agregue una ruta de prioridad baja para la página _Host como último punto de conexión:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapBlazorHub();
    +   endpoints.MapFallbackToPage("/_Host");
    });
    
  5. Agregue componentes enrutables al proyecto.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Uso de componentes enrutables en una aplicación MVC

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones MVC, haga lo siguiente:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    

    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, consulte Migración de ASP.NET Core 3.1 a 5.0.

  3. Agregue una vista _Host al proyecto con el contenido siguiente.

    Views/Home/_Host.cshtml:

    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    Los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. Agregue una acción al controlador Home.

    Controllers/HomeController.cs:

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. En los puntos de conexión Startup.Configure de Startup.cs, agregue una ruta de prioridad baja para la acción del controlador que devuelva la vista _Host:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapBlazorHub();
    +   endpoints.MapFallbackToController("Blazor", "Home");
    });
    
  6. Agregue componentes enrutables al proyecto.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Representación de componentes a partir de una página o vista

Esta sección pertenece a la adición de componentes a páginas o vistas, donde los componentes no son enrutables directamente desde las solicitudes del usuario.

Para representar un componente a partir de una página o vista, use el asistente de etiquetas de componente.

Representación de componentes interactivos con estado

Los componentes interactivos con estado se pueden agregar a una página de Razor o una vista.

Cuando se representa la página o la vista:

  • El componente se representa previamente con la página o la vista.
  • Se pierde el estado inicial del componente que se usa para la representación previa.
  • Cuando se establece la conexión SignalR, se crea un estado del componente.

La siguiente página de Razor representa un componente Counter:

<h1>My Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Representación de componentes no interactivos

En la siguiente página de Razor, el componente Counter se representa de forma estática con un valor inicial que se especifica mediante un formulario. Como el componente se representa de forma estática, no es interactivo:

<h1>My Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Espacios de nombres de componentes

Si usa una carpeta personalizada para contener los componentes _ViewImports.cshtml del proyecto, agregue el espacio de nombres que representa la carpeta a la página o vista, o bien al archivo Razor. En el ejemplo siguiente:

  • Los componentes se almacenan en la carpeta Components del proyecto.
  • El marcador de posición {APP NAMESPACE} es el espacio de nombres del proyecto. Components representa el nombre de la carpeta.
@using {APP NAMESPACE}.Components

El archivo _ViewImports.cshtml se encuentra en la carpeta Pages de una aplicación Razor Pages o en la carpeta Views de una aplicación de MVC.

Para obtener más información, vea Componentes de Razor de ASP.NET Core.

Recursos de Blazor WebAssembly adicionales

La integración de componentes Razor en aplicaciones de Razor Pages y MVC en una solución Blazor WebAssembly hospedada es compatible con ASP.NET Core en .NET 5 o versiones posteriores. Seleccione una versión .NET 5 o posterior de este artículo.

Los componentes Razor se pueden integrar en aplicaciones de Razor Pages y MVC en una aplicación Blazor Server. Cuando se representa la página o la vista, los componentes se pueden representar previamente al mismo tiempo.

Después de configurar el proyecto, use la guía que aparece en las secciones siguientes en función de los requisitos del proyecto:

Configuración

Una aplicación Razor Pages o MVC existente puede integrar componentes Razor en páginas y vistas:

  1. En el archivo de diseño del proyecto:

    • Agregue la siguiente etiqueta <base> al elemento <head> en Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

      + <base href="~/" />
      

      El valor href (la ruta de acceso base de la aplicación) del ejemplo anterior da por hecho que la aplicación reside en la ruta de acceso URL raíz (/). Si la aplicación es una subaplicación, siga las instrucciones de la sección Ruta de acceso base de la aplicación del artículo Hospedaje e implementación de ASP.NET Core Blazor.

    • Agregue una etiqueta <script> para el script blazor.server.js inmediatamente antes de la sección de representación Scripts.

      Pages/Shared/_Layout.cshtml (Razor Pages) o Views/Shared/_Layout.cshtml (MVC):

          ...
      +   <script src="_framework/blazor.server.js"></script>
      
          @await RenderSectionAsync("Scripts", required: false)
      </body>
      

      El marco agrega el script blazor.server.js a la aplicación. No es necesario agregar manualmente un archivo de script blazor.server.js a la aplicación.

  2. Agregue un archivo imports a la carpeta raíz del proyecto con el contenido siguiente. Cambie el marcador de posición {APP NAMESPACE} al espacio de nombres del proyecto.

    _Imports.razor:

    @using System.Net.Http
    @using Microsoft.AspNetCore.Authorization
    @using Microsoft.AspNetCore.Components.Authorization
    @using Microsoft.AspNetCore.Components.Forms
    @using Microsoft.AspNetCore.Components.Routing
    @using Microsoft.AspNetCore.Components.Web
    @using Microsoft.JSInterop
    @using {APP NAMESPACE}
    
  3. Registre el servicio Blazor Server en Startup.ConfigureServices.

    Startup.cs:

    + services.AddServerSideBlazor();
    
  4. Agregue el punto de conexión Blazor Hub a los puntos de conexión (app.UseEndpoints) de Startup.Configure.

    Startup.cs:

    + endpoints.MapBlazorHub();
    
  5. Integre los componentes en cualquier página o vista. Por ejemplo, agregue un componente Counter a la carpeta Shared del proyecto.

    Pages/Shared/Counter.razor (Razor Pages) o Views/Shared/Counter.razor (MVC):

    <h1>Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    

    Razor Pages:

    En la página Index del proyecto de una aplicación Razor Pages, agregue el espacio de nombres del componente Counter e inserte el componente en la página. Cuando se carga la página Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Pages/Index.cshtml:

    @page
    @using {APP NAMESPACE}.Pages.Shared
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

    En el ejemplo anterior, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres de la aplicación.

    MVC:

    En la vista Index del proyecto de una aplicación MVC, agregue el espacio de nombres del componente Counter e inserte el componente en la vista. Cuando se carga la vista Index, el componente Counter se representa previamente en ella. En el ejemplo siguiente, reemplace el marcador de posición {APP NAMESPACE} por el espacio de nombres del proyecto.

    Views/Home/Index.cshtml:

    @using {APP NAMESPACE}.Views.Shared
    @{
        ViewData["Title"] = "Home Page";
    }
    
    <div>
        <component type="typeof(Counter)" render-mode="ServerPrerendered" />
    </div>
    

Para obtener más información, vea la sección Representación de componentes a partir de una página o vista.

Uso de componentes enrutables en una aplicación Razor Pages

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones Razor Pages:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    
  3. Agregue una página _Host al proyecto con el contenido siguiente.

    Pages/_Host.cshtml:

    @page "/blazor"
    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    Los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. En los puntos de conexión Startup.Configure de Startup.cs, agregue una ruta de prioridad baja para la página _Host como último punto de conexión:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapBlazorHub();
    +   endpoints.MapFallbackToPage("/_Host");
    });
    
  5. Agregue componentes enrutables al proyecto.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  6. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Uso de componentes enrutables en una aplicación MVC

Esta sección pertenece a la incorporación de componentes que se pueden enrutar directamente desde las solicitudes del usuario.

Para admitir componentes Razor enrutables en aplicaciones MVC, haga lo siguiente:

  1. Siga las instrucciones de la sección Configuración.

  2. Agregue un componente App a la raíz del proyecto con el contenido siguiente.

    App.razor:

    @using Microsoft.AspNetCore.Components.Routing
    
    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="routeData" />
        </Found>
        <NotFound>
            <h1>Page not found</h1>
            <p>Sorry, but there's nothing here!</p>
        </NotFound>
    </Router>
    
  3. Agregue una vista _Host al proyecto con el contenido siguiente.

    Views/Home/_Host.cshtml:

    @{
        Layout = "_Layout";
    }
    
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    

    Los componentes usan el archivo compartido _Layout.cshtml para su diseño.

    RenderMode configura si el componente App:

    • Se representa previamente en la página.
    • Se representa como HTML estático en la página o si incluye la información necesaria para arrancar una aplicación Blazor desde el agente de usuario.

    Para obtener más información sobre la aplicación auxiliar de etiquetas de componentes, como pasar parámetros y configurar RenderMode, vea Asistente de etiquetas de componente en ASP.NET Core.

  4. Agregue una acción al controlador Home.

    Controllers/HomeController.cs:

    public IActionResult Blazor()
    {
       return View("_Host");
    }
    
  5. En los puntos de conexión Startup.Configure de Startup.cs, agregue una ruta de prioridad baja para la acción del controlador que devuelva la vista _Host:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapBlazorHub();
    +   endpoints.MapFallbackToController("Blazor", "Home");
    });
    
  6. Agregue componentes enrutables al proyecto.

    Pages/RoutableCounter.razor:

    @page "/routable-counter"
    
    <h1>Routable Counter</h1>
    
    <p>Current count: @currentCount</p>
    
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
    
    @code {
        private int currentCount = 0;
    
        private void IncrementCount()
        {
            currentCount++;
        }
    }
    
  7. Ejecute el proyecto y vaya al componente RoutableCounter enrutable en /routable-counter.

Para obtener más información sobre los espacios de nombres, vea la sección Espacios de nombres de componentes.

Representación de componentes a partir de una página o vista

Esta sección pertenece a la adición de componentes a páginas o vistas, donde los componentes no son enrutables directamente desde las solicitudes del usuario.

Para representar un componente a partir de una página o vista, use el asistente de etiquetas de componente.

Representación de componentes interactivos con estado

Los componentes interactivos con estado se pueden agregar a una página de Razor o una vista.

Cuando se representa la página o la vista:

  • El componente se representa previamente con la página o la vista.
  • Se pierde el estado inicial del componente que se usa para la representación previa.
  • Cuando se establece la conexión SignalR, se crea un estado del componente.

La siguiente página de Razor representa un componente Counter:

<h1>My Razor Page</h1>

<component type="typeof(Counter)" render-mode="ServerPrerendered" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Representación de componentes no interactivos

En la siguiente página de Razor, el componente Counter se representa de forma estática con un valor inicial que se especifica mediante un formulario. Como el componente se representa de forma estática, no es interactivo:

<h1>My Razor Page</h1>

<form>
    <input type="number" asp-for="InitialValue" />
    <button type="submit">Set initial value</button>
</form>

<component type="typeof(Counter)" render-mode="Static" 
    param-InitialValue="InitialValue" />

@functions {
    [BindProperty(SupportsGet=true)]
    public int InitialValue { get; set; }
}

Para obtener más información, vea Asistente de etiquetas de componente en ASP.NET Core.

Espacios de nombres de componentes

Si usa una carpeta personalizada para contener los componentes _ViewImports.cshtml del proyecto, agregue el espacio de nombres que representa la carpeta a la página o vista, o bien al archivo Razor. En el ejemplo siguiente:

  • Los componentes se almacenan en la carpeta Components del proyecto.
  • El marcador de posición {APP NAMESPACE} es el espacio de nombres del proyecto. Components representa el nombre de la carpeta.
@using {APP NAMESPACE}.Components

El archivo _ViewImports.cshtml se encuentra en la carpeta Pages de una aplicación Razor Pages o en la carpeta Views de una aplicación de MVC.

Para obtener más información, vea Componentes de Razor de ASP.NET Core.

Recursos de Blazor Server adicionales