Consumo de componentes ASP.NET Core Razor de bibliotecas de clases Razor (RCL)
Nota
Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulta la versión .NET 8 de este artículo.
Los componentes se pueden compartir entre proyectos en una biblioteca de clases de Razor (RCL). Incluye componentes y recursos estáticos en una aplicación de:
- Otro proyecto de la solución.
- Una biblioteca de .NET a la que se hace referencia.
- Un paquete NuGet.
Del mismo modo que los componentes son tipos normales de .NET, los componentes proporcionados por una RCL son ensamblados .NET normales.
Creación de una RCL
- Crea un nuevo proyecto.
- En el cuadro de diálogo Crear un proyecto, selecciona Biblioteca de clases de Razor en la lista de plantillas de proyecto de ASP.NET Core. Selecciona Siguiente.
- En el cuadro de diálogo Configura tu nuevo proyecto, indica un nombre de proyecto en el campo Nombre del proyecto. En los ejemplos de este tema se usa el nombre de proyecto
ComponentLibrary
. Selecciona Siguiente. - En el cuadro de diálogo Información adicional, no selecciones Páginas y vistas de soporte. Selecciona Crear.
- Agrega la RCL a una solución:
- Abre la solución.
- Haz clic con el botón derecho en el Explorador de soluciones. Selecciona Agregar>Proyecto existente.
- Navega hasta el archivo del proyecto de la RCL.
- Selecciona el archivo de proyecto de la RCL (
.csproj
).
- Agrega una referencia a la RCL desde la aplicación:
- Haz clic con el botón derecho en el proyecto de la aplicación. Selecciona Agregar>Referencia de proyecto.
- Selecciona el proyecto de la RCL. Selecciona Aceptar.
Consumo de un componente Razor de una RCL
Para consumir los componentes de una RCL de otro proyecto, usa cualquiera de los métodos siguientes:
- Usa el nombre completo del tipo de componente, que incluye el espacio de nombres de la RCL.
- Los componentes individuales se pueden agregar por nombre sin el espacio de nombres de la RCL si la directiva
@using
de Razor declara el espacio de nombres de la RCL. Sigue uno de estos procedimientos:- Agrega la directiva
@using
a los componentes individuales. - Incluye la directiva
@using
en el archivo de nivel superior_Imports.razor
a fin de que los componentes de la biblioteca estén disponibles para un proyecto completo. Agrega la directiva a un archivo_Imports.razor
en cualquier nivel para aplicar el espacio de nombres a un solo componente o a un conjunto de componentes dentro de una carpeta. Cuando se usa un archivo_Imports.razor
, los componentes individuales no requieren una directiva@using
para el espacio de nombres de la RCL.
- Agrega la directiva
En los ejemplos siguientes, ComponentLibrary
es una RCL que contiene el componente Component1
. El componente Component1
es un componente de ejemplo que se agrega automáticamente a una RCL creada a partir de la plantilla de proyecto de RCL que no se crea para admitir páginas y vistas.
Component1.razor
en la RCL ComponentLibrary
:
<div class="my-component">
This component is defined in the <strong>ComponentLibrary</strong> package.
</div>
En la aplicación que consume la RCL, haz referencia al componente Component1
mediante su espacio de nombres, como se muestra en el ejemplo siguiente.
ConsumeComponent1.razor
:
@page "/consume-component-1"
<h1>Consume component (full namespace example)</h1>
<ComponentLibrary.Component1 />
También puedes agregar una directiva @using
y usar el componente sin su espacio de nombres. La siguiente directiva @using
también puede aparecer en cualquier archivo _Imports.razor
en el archivo actual o situado por encima del mismo.
ConsumeComponent2.razor
:
@page "/consume-component-2"
@using ComponentLibrary
<h1>Consume component (<code>@@using</code> example)</h1>
<Component1 />
En el caso de los componentes de biblioteca que usan el aislamiento de CSS, los estilos de componente se ponen automáticamente a disposición de la aplicación de consumo. No es necesario vincular ni importar manualmente las hojas de estilos de componentes individuales de la biblioteca ni su archivo CSS agrupado en la aplicación que consume la biblioteca. La aplicación usa importaciones CSS para hacer referencia a los estilos agrupados de la RCL. Los estilos agrupados no se publican como recursos web estáticos de la aplicación que consume la biblioteca. Para una biblioteca de clases denominada ClassLib
y una aplicación Blazor con una hoja de estilos BlazorSample.styles.css
, la hoja de estilos de la RCL se importa automáticamente en la parte superior de la hoja de estilos de la aplicación en tiempo de compilación:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
En los ejemplos anteriores, la hoja de estilos de Component1
(Component1.razor.css
) se agrupa automáticamente.
Component1.razor.css
en la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
La imagen de fondo también se incluye desde la plantilla de proyecto de RCL y reside en la carpeta wwwroot
de la RCL.
wwwroot/background.png
en la RCL ComponentLibrary
:
Para proporcionar estilos de componentes de biblioteca adicionales de hojas de estilos en la carpeta wwwroot
de la biblioteca, agrega etiquetas <link>
de hoja de estilos al consumidor de la RCL, como se muestra en el ejemplo siguiente.
Importante
Por lo general, los componentes de biblioteca usan el aislamiento CSS para agrupar y proporcionar estilos de componentes. Los estilos de componentes que se basan en el aislamiento CSS están disponibles automáticamente para la aplicación que usa la RCL. No es necesario vincular ni importar manualmente las hojas de estilos de componentes individuales de la biblioteca ni su archivo CSS agrupado en la aplicación que consume la biblioteca. El ejemplo siguiente es para proporcionar hojas de estilos globales fuera del aislamiento CSS, que normalmente no es un requisito para las aplicaciones típicas que consumen RCL.
La siguiente imagen de fondo se usa en el ejemplo siguiente. Si implementas el ejemplo que se muestra en esta sección, haz clic con el botón derecho en la imagen para guardarla localmente.
wwwroot/extra-background.png
en la RCL ComponentLibrary
:
Agrega una nueva hoja de estilos a la RCL con una clase extra-style
.
wwwroot/additionalStyles.css
en la RCL ComponentLibrary
:
.extra-style {
border: 2px dashed blue;
padding: 1em;
margin: 1em 0;
background-image: url('extra-background.png');
}
Agrega un componente a la RCL que use la clase extra-style
.
ExtraStyles.razor
en la RCL ComponentLibrary
:
<div class="extra-style">
<p>
This component is defined in the <strong>ComponentLibrary</strong> package.
</p>
</div>
Agrega una página a la aplicación que use el componente ExtraStyles
de la RCL.
ConsumeComponent3.razor
:
@page "/consume-component-3"
@using ComponentLibrary
<h1>Consume component (<code>additionalStyles.css</code> example)</h1>
<ExtraStyles />
Crea un vínculo a la hoja de estilos de la biblioteca en el marcado <head>
de la aplicación (ubicación del contenido de <head>
):
Blazor Web App:
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
Aplicaciones Blazor WebAssembly independientes:
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
En el caso de los componentes de biblioteca que usan el aislamiento de CSS, los estilos de componente se ponen automáticamente a disposición de la aplicación de consumo. No es necesario vincular ni importar manualmente las hojas de estilos de componentes individuales de la biblioteca ni su archivo CSS agrupado en la aplicación que consume la biblioteca. La aplicación usa importaciones CSS para hacer referencia a los estilos agrupados de la RCL. Los estilos agrupados no se publican como recursos web estáticos de la aplicación que consume la biblioteca. Para una biblioteca de clases denominada ClassLib
y una aplicación Blazor con una hoja de estilos BlazorSample.styles.css
, la hoja de estilos de la RCL se importa automáticamente en la parte superior de la hoja de estilos de la aplicación en tiempo de compilación:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
En los ejemplos anteriores, la hoja de estilos de Component1
(Component1.razor.css
) se agrupa automáticamente.
Component1.razor.css
en la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
La imagen de fondo también se incluye desde la plantilla de proyecto de RCL y reside en la carpeta wwwroot
de la RCL.
wwwroot/background.png
en la RCL ComponentLibrary
:
El componente de ejemplo Component1
de la RCL usa la imagen de fondo y la hoja de estilos siguientes. No es necesario agregar estos recursos estáticos a una nueva RCL creada a partir de la plantilla de proyecto de RCL, ya que la plantilla de proyecto los agrega automáticamente.
wwwroot/background.png
en la RCL ComponentLibrary
:
wwwroot/styles.css
en la RCL ComponentLibrary
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
Para proporcionar la clase CSS my-component
de Component1
, enlaza a la hoja de estilos de la biblioteca en el marcado de la aplicación <head>
(ubicación del <head>
contenido):
<link href="_content/ComponentLibrary/styles.css" rel="stylesheet" />
Hacer que los componentes enrutables estén disponibles en la RCL
Para que los componentes enrutables de la RCL estén disponibles para las solicitudes directas, el ensamblado de la RCL debe revelarse al enrutador de la aplicación.
Abre el componente App
de la aplicación (App.razor
). Asigna una colección Assembly al parámetro AdditionalAssemblies del componente Router para incluir el ensamblado del RCL. En el ejemplo siguiente, el componente ComponentLibrary.Component1
se usa para detectar el ensamblado de la RCL.
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
Para obtener más información, consulta Enrutamiento y navegación de Blazor de ASP.NET Core.
Creación de una RCL con recursos estáticos en la carpeta wwwroot
Los recursos estáticos de una RCL están disponibles para cualquier aplicación que use la biblioteca.
Coloca los recursos estáticos en la carpeta wwwroot
de la RCL y haz referencia a estos con la siguiente ruta de acceso en la aplicación: _content/{PACKAGE ID}/{PATH AND FILE NAME}
. El marcador de posición {PACKAGE ID}
es el id. de paquete de la biblioteca. El id. de paquete tiene como valor predeterminado el nombre de ensamblado del proyecto si <PackageId>
no se especifica en el archivo del proyecto. El marcador de posición {PATH AND FILE NAME}
es la ruta de acceso y el nombre de archivo en wwwroot
. Este formato de ruta de acceso también se usa en la aplicación para los recursos estáticos proporcionados por un paquete NuGet agregado a la RCL.
En el siguiente ejemplo se muestra el uso de recursos estáticos de RCL con una RCL llamada ComponentLibrary
y una aplicación Blazor que use la RCL. La aplicación tiene una referencia de proyecto para la RCL ComponentLibrary
.
La siguiente imagen de Jeep® se usa en el ejemplo de esta sección. Si implementas el ejemplo que se muestra en esta sección, haz clic con el botón derecho en la imagen para guardarla localmente.
wwwroot/jeep-yj.png
en la RCL ComponentLibrary
:
Agrega el siguiente componente JeepYJ
a la RCL.
JeepYJ.razor
en la RCL ComponentLibrary
:
<h3>ComponentLibrary.JeepYJ</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
Agrega el siguiente componente Jeep
a la aplicación que use la RCL ComponentLibrary
. El componente Jeep
usa:
- La imagen de Jeep YJ® de la carpeta
wwwroot
de la RCLComponentLibrary
. - El componente
JeepYJ
de la RCL.
Jeep.razor
:
@page "/jeep"
@using ComponentLibrary
<div style="float:left;margin-right:10px">
<h3>Direct use</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
</div>
<JeepYJ />
<p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
</p>
Componente Jeep
representado:
Para obtener más información, consulta Interfaz de usuario reutilizable de Razor en bibliotecas de clases con ASP.NET Core.
Creación de una RCL con archivos JavaScript colocados con componentes
La colocación de archivos de JavaScript (JS) para componentes Razor es una manera cómoda de organizar los scripts en una aplicación.
Los componentes Razor de aplicaciones Blazor intercalan archivos JS mediante la extensión .razor.js
y se pueden direccionar públicamente mediante la ruta de acceso al archivo del proyecto:
{PATH}/{COMPONENT}.razor.js
- El marcador de posición
{PATH}
es la ruta de acceso al componente. - El marcador de posición
{COMPONENT}
es el componente.
Cuando se publica la aplicación, el marco mueve automáticamente el script a la raíz web. Los scripts se mueven a bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
, donde los marcadores de posición son:
{TARGET FRAMEWORK MONIKER}
es la Moniker de la plataforma de destino (TFM).{PATH}
es la ruta de acceso al componente.{COMPONENT}
es el nombre del componente.
No se requiere ningún cambio en la dirección URL relativa del script, ya que Blazor se encarga de colocar el archivo JS en los recursos estáticos publicados por ti.
Esta sección y los ejemplos siguientes se centran principalmente en explicar la intercalación de archivos JS. En el primer ejemplo se muestra un archivo intercalado JS con una función normal JS. En el segundo ejemplo se muestra el uso de un módulo para cargar una función, que es el enfoque recomendado para la mayoría de las aplicaciones de producción. Las llamadas JS desde .NET se tratan completamente en Llamar a funciones de JavaScript desde métodos de .NET en ASP.NET Core Blazor, donde hay más explicaciones de la BlazorJS API con ejemplos adicionales. La eliminación de componentes, que está presente en el segundo ejemplo, se trata en ASP.NET Core Razor ciclo de vida de componentes.
El siguiente JsCollocation1
componente carga un script a través de un HeadContent
componente y llama a una JS función con IJSRuntime.InvokeAsync. El marcador de posición {PATH}
es la ruta de acceso al componente.
Importante
Si usas el código siguiente para una demostración en una aplicación de prueba, cambie el {PATH}
marcador de posición a la ruta de acceso del componente (ejemplo: Components/Pages
en .NET 8 o posterior o Pages
en .NET 7 o anterior). En una Blazor Web App (.NET 8 o posterior), el componente requiere un modo de representación interactivo aplicado globalmente a la aplicación o a la definición del componente.
Agrega el siguiente script después del script Blazor (ubicación del Blazor script de inicio ):
<script src="{PATH}/JsCollocation1.razor.js"></script>
Componente JsCollocation1
({PATH}/JsCollocation1.razor
):
@page "/js-collocation-1"
@inject IJSRuntime JS
<PageTitle>JS Collocation 1</PageTitle>
<h1>JS Collocation Example 1</h1>
<button @onclick="ShowPrompt">Call showPrompt1</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private string? result;
public async void ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
El archivo colocado JS se coloca junto al archivo de JsCollocation1
componente con el nombre de archivoJsCollocation1.razor.js
. En el componente JsCollocation1
, se hace referencia al script en la ruta de acceso del archivo intercalado. En el ejemplo siguiente, la función showPrompt1
acepta el nombre del usuario de un Window prompt()
y lo devuelve al componente JsCollocation1
para mostrarlo.
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
El enfoque anterior no se recomienda para su uso general en aplicaciones de producción porque contamina el cliente con funciones globales. Un mejor enfoque para las aplicaciones de producción es usar módulos JS. Los mismos principios generales se aplican a la carga JS de un módulo desde un archivo combinado JS, como se muestra en el siguiente ejemplo.
El método del siguiente componente JsCollocation2
OnAfterRenderAsync
carga un módulo JS en module
, que es una IJSObjectReference de la clase de componente. module
se usa para llamar a la función showPrompt2
. El marcador de posición {PATH}
es la ruta de acceso al componente.
Importante
Si usas el código siguiente para una demostración en una aplicación de prueba, cambia el {PATH}
marcador de posición a la ruta de acceso del componente. En una Blazor Web App (.NET 8 o posterior), el componente requiere un modo de representación interactivo aplicado globalmente a la aplicación o a la definición del componente.
Componente JsCollocation2
({PATH}/JsCollocation2.razor
):
@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>JS Collocation 2</PageTitle>
<h1>JS Collocation Example 2</h1>
<button @onclick="ShowPrompt">Call showPrompt2</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private IJSObjectReference? module;
private string? result;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
/*
Change the {PATH} placeholder in the next line to the path of
the collocated JS file in the app. Examples:
./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
*/
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./{PATH}/JsCollocation2.razor.js");
}
}
public async void ShowPrompt()
{
if (module is not null)
{
result = await module.InvokeAsync<string>(
"showPrompt2", "What's your name?");
StateHasChanged();
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
await module.DisposeAsync();
}
}
}
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
El uso de scripts y módulos para JS intercalados en una biblioteca de clases (RCL) de Razor solo se admite para el mecanismo de interoperabilidad JS de Blazor basado en la interfaz de IJSRuntime. Si vas a implementar interoperabilidad JavaScript [JSImport]
/[JSExport]
, consulta Interoperabilidad JSImport/JSExport de JavaScript con ASP.NET Core Blazor.
En el caso de scripts o módulos proporcionados por una biblioteca de clases (RCL) de Razor mediante la interoperabilidad de JS basada en IJSRuntime, se usa la siguiente ruta de acceso:
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- El segmento de trazado del directorio actual (
./
) es necesario para crear la ruta de recurso estático correcta para el archivo JS. - El marcador de posición
{PACKAGE ID}
es el identificador de paquete de la RCL (o el nombre de la biblioteca para una biblioteca de clases a la que hace referencia la aplicación). - El marcador de posición
{PATH}
es la ruta de acceso al componente. Si un componente Razor se encuentra en la raíz de la RCL, no se incluye el segmento de ruta. - El marcador de posición
{COMPONENT}
es el componente. - El marcador de posición
{EXTENSION}
coincide con la extensión de la componente, ya searazor
ocshtml
.
En el ejemplo siguiente de aplicación Blazor:
- El identificador de paquete de la RCL es
AppJS
. - Los scripts de un módulo se cargan para el componente
JsCollocation3
(JsCollocation3.razor
). - El componente
JsCollocation3
está en la carpetaComponents/Pages
de la RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
Proporcionar componentes y recursos estáticos a varias aplicaciones de Blazor hospedadas
Para más información, consulte Varias aplicaciones de ASP.NET Core Blazor WebAssembly hospedadas.
Analizador de compatibilidad del explorador del cliente
Las aplicaciones del lado del cliente aprovechan toda la superficie de las API de .NET, pero no todas las API de .NET son compatibles con WebAssembly debido a las limitaciones del entorno aislado del navegador. Las API no compatibles inician la excepción PlatformNotSupportedException cuando se ejecutan en WebAssembly. Un analizador de compatibilidad de plataforma advierte al desarrollador cuando la aplicación usa API que no son compatibles con las plataformas de destino de la aplicación. Para las aplicaciones del lado del cliente, esto significa comprobar que las API son compatibles con los exploradores. La anotación de API de .NET Framework para el analizador de compatibilidad es un proceso constante, por lo que no todas las API de .NET Framework están anotadas actualmente.
Los objetos Blazor Web App que permiten componentes interactivos WebAssembly, aplicaciones Blazor WebAssembly y proyectos RCL habilitan automáticamente las comprobaciones de compatibilidad del explorador agregando browser
como plataforma compatible con el elemento MSBuild SupportedPlatform
. Los desarrolladores de bibliotecas pueden agregar manualmente el elemento SupportedPlatform
al archivo de proyecto de una biblioteca para habilitar la característica:
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
Al crear una biblioteca, especifique browser
en UnsupportedOSPlatformAttribute para indicar que los exploradores no admiten una API determinada:
using System.Runtime.Versioning;
...
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
...
}
Para más información, vea Anotación de API como no compatibles en plataformas específicas (repositorio dotnet/designs
de GitHub).
Aislamiento de JavaScript en módulos de JavaScript
Blazor permite el aislamiento de JavaScript en módulos de JavaScript estándar. El aislamiento de JavaScript reporta las siguientes ventajas:
- El código JavaScript importado no contamina el espacio de nombres global.
- No es necesario que los consumidores de la biblioteca y los componentes importen manualmente el código JavaScript relacionado.
Para más información, vea Llamada a funciones de JavaScript desde métodos de .NET en Blazor de ASP.NET Core.
Prevención del recorte de los métodos de .NET invocables de JavaScript
La revinculación en tiempo de ejecución recorta los métodos de .NET invocables de la instancia de clase JavaScript a menos que se conserven explícitamente. Para obtener más información, vea Llamada a métodos de .NET desde funciones de JavaScript en ASP.NET Core Blazor.
Compilación, empaquetado y envío de bibliotecas a NuGet
Dado que las bibliotecas de clases Razor que contienen componentes Razor son bibliotecas estándar de .NET, se empaquetan y se envían a NuGet de la misma manera que cualquier otra biblioteca. El empaquetado se realiza mediante el comando dotnet pack
en un shell de comandos:
dotnet pack
Cargue el paquete en NuGet usando el comando dotnet nuget push
en un shell de comandos.
Marcas comerciales
Jeep y Jeep YJ son marcas registradas de FCA US LLC (Stellantis NV).
Recursos adicionales
- Interfaz de usuario reutilizable de Razor en bibliotecas de clases con ASP.NET Core
- Uso de las API de ASP.NET Core en una biblioteca de clases
- Adición de un archivo de configuración del recortador de lenguaje intermedio (IL) XML a una biblioteca
- Compatibilidad de aislamiento de CSS con bibliotecas de clases Razor