Crear una interfaz de usuario reutilizable mediante el proyecto de biblioteca de clases de Razor en ASP.NET CoreCreate reusable UI using the Razor class library project in ASP.NET Core

Por Rick AndersonBy Rick Anderson

Las vistas, páginas, controladores, modelos de páginas, componentes de Razor, componentes de vistay modelos de datos de Razor se pueden integrar en una biblioteca de clases de Razor (RCL).Razor views, pages, controllers, page models, Razor components, View components, and data models can be built into a Razor class library (RCL). Las RCL se pueden empaquetar y reutilizar.The RCL can be packaged and reused. Las aplicaciones pueden incluir la RCL y reemplazar las vistas y páginas que contienen.Applications can include the RCL and override the views and pages it contains. Cuando existe una vista, vista parcial o página de Razor tanto en la aplicación web como en la RCL, tendrá prioridad el marcado de Razor (archivo .cshtml) de la aplicación web.When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence.

Vea o descargue el código de ejemplo (cómo descargarlo)View or download sample code (how to download)

Crear una biblioteca de clases que contenga interfaz de usuario de RazorCreate a class library containing Razor UI

  • En Visual Studio, seleccione crear nuevo proyecto nuevo.From Visual Studio select Create new a new project.
  • Seleccione biblioteca de clases de Razor > siguiente.Select Razor Class Library > Next.
  • Asigne a la biblioteca el nombre (por ejemplo, "RazorClassLib"), > crear.Name the library (for example, "RazorClassLib"), > Create. Para evitar un conflicto de nombres de archivo con la biblioteca de vistas generada, asegúrese de que el nombre de la biblioteca no acaba en .Views.To avoid a file name collision with the generated view library, ensure the library name doesn't end in .Views.
  • Seleccione páginas y vistas de soporte técnico si necesita admitir vistas.Select Support pages and views if you need to support views. De forma predeterminada, solo se admiten Razor Pages.By default, only Razor Pages are supported. Seleccione Crear.Select Create.

De forma predeterminada, la plantilla de la biblioteca de clases de Razor (RCL) utiliza el desarrollo de componentes de Razor.The Razor class library (RCL) template defaults to Razor component development by default. La opción páginas y vistas de soporte técnico admite páginas y vistas.The Support pages and views option supports pages and views.

Agregue archivos de Razor a la RCL.Add Razor files to the RCL.

Las plantillas ASP.NET Core suponen que el contenido de RCL se encuentra en la carpeta áreas .The ASP.NET Core templates assume the RCL content is in the Areas folder. Consulte diseño de páginas de RCL para crear un RCL que exponga contenido en ~/Pages en lugar de ~/Areas/Pages.See RCL Pages layout to create an RCL that exposes content in ~/Pages rather than ~/Areas/Pages.

Contenido de RCL de referenciaReference RCL content

Los siguientes elementos pueden hacer referencia a la RCL:The RCL can be referenced by:

Reemplazar vistas, vistas parciales y páginasOverride views, partial views, and pages

Cuando existe una vista, vista parcial o página de Razor tanto en la aplicación web como en la RCL, tendrá prioridad el marcado de Razor (archivo .cshtml) de la aplicación web.When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence. Por ejemplo, agregue WebApp1/areas/mi Feature/pages/Page1. cshtml a WebApp1 y Page1 en WebApp1 tendrá prioridad sobre PÁGINA1 en RCL.For example, add WebApp1/Areas/MyFeature/Pages/Page1.cshtml to WebApp1, and Page1 in the WebApp1 will take precedence over Page1 in the RCL.

En la descarga de ejemplo, cambie el nombre WebApp1/Areas/MyFeature2 por WebApp1/Areas/MyFeature para comprobar la prioridad.In the sample download, rename WebApp1/Areas/MyFeature2 to WebApp1/Areas/MyFeature to test precedence.

Copie la vista parcial RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml en WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml.Copy the RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml partial view to WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Actualice el marcado para señalar la nueva ubicación.Update the markup to indicate the new location. Compile y ejecute la aplicación para comprobar si se está usando la versión de la vista parcial de la aplicación.Build and run the app to verify the app's version of the partial is being used.

Diseño de páginas RCLRCL Pages layout

Para hacer referencia al contenido de RCL como si formara parte de la carpeta páginas de la aplicación Web, cree el proyecto RCL con la siguiente estructura de archivos:To reference RCL content as though it is part of the web app's Pages folder, create the RCL project with the following file structure:

  • RazorUIClassLib/páginasRazorUIClassLib/Pages
  • RazorUIClassLib/páginas/compartidoRazorUIClassLib/Pages/Shared

Supongamos que RazorUIClassLib/pages/Shared contiene dos archivos parciales: _Header. cshtml y _Footer. cshtml.Suppose RazorUIClassLib/Pages/Shared contains two partial files: _Header.cshtml and _Footer.cshtml. Las etiquetas de <partial> se pueden agregar al archivo _Layout. cshtml :The <partial> tags could be added to _Layout.cshtml file:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Creación de un RCL con recursos estáticosCreate an RCL with static assets

Una RCL puede requerir recursos estáticos complementarios a los que puede hacer referencia el RCL o la aplicación de consumo de RCL.An RCL may require companion static assets that can be referenced by either the RCL or the consuming app of the RCL. ASP.NET Core permite crear RCLs que incluyen recursos estáticos que están disponibles para una aplicación de consumo.ASP.NET Core allows creating RCLs that include static assets that are available to a consuming app.

Para incluir los recursos complementarios como parte de un RCL, cree una carpeta wwwroot en la biblioteca de clases e incluya los archivos necesarios en esa carpeta.To include companion assets as part of an RCL, create a wwwroot folder in the class library and include any required files in that folder.

Al empaquetar un RCL, todos los recursos complementarios de la carpeta wwwroot se incluyen automáticamente en el paquete.When packing an RCL, all companion assets in the wwwroot folder are automatically included in the package.

Excluir recursos estáticosExclude static assets

Para excluir recursos estáticos, agregue la ruta de exclusión deseada al grupo de propiedades $(DefaultItemExcludes) en el archivo de proyecto.To exclude static assets, add the desired exclusion path to the $(DefaultItemExcludes) property group in the project file. Separe las entradas con un punto y coma (;).Separate entries with a semicolon (;).

En el ejemplo siguiente, la hoja de estilos lib. CSS de la carpeta wwwroot no se considera un recurso estático y no se incluye en el RCL publicado:In the following example, the lib.css stylesheet in the wwwroot folder isn't considered a static asset and isn't included in the published RCL:

<PropertyGroup>
  <DefaultItemExcludes>$(DefaultItemExcludes);wwwroot\lib.css</DefaultItemExcludes>
</PropertyGroup>

Integración de TypescriptTypescript integration

Para incluir los archivos TypeScript en un RCL:To include TypeScript files in an RCL:

  1. Coloque los archivos TypeScript ( . ts) fuera de la carpeta wwwroot .Place the TypeScript files (.ts) outside of the wwwroot folder. Por ejemplo, coloque los archivos en una carpeta de cliente .For example, place the files in a Client folder.

  2. Configure el resultado de la compilación de TypeScript para la carpeta wwwroot .Configure the TypeScript build output for the wwwroot folder. Establezca la propiedad TypescriptOutDir dentro de un PropertyGroup en el archivo de proyecto:Set the TypescriptOutDir property inside of a PropertyGroup in the project file:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  3. Incluya el destino de TypeScript como una dependencia del destino de ResolveCurrentProjectStaticWebAssets agregando el siguiente destino dentro de un PropertyGroup en el archivo de proyecto:Include the TypeScript target as a dependency of the ResolveCurrentProjectStaticWebAssets target by adding the following target inside of a PropertyGroup in the project file:

    <ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
      CompileTypeScript;
      $(ResolveCurrentProjectStaticWebAssetsInputs)
    </ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
    

Consumo de contenido de una RCL a la que se hace referenciaConsume content from a referenced RCL

Los archivos incluidos en la carpeta wwwroot de RCL se exponen a RCL o a la aplicación de consumo en el prefijo _content/{LIBRARY NAME}/.The files included in the wwwroot folder of the RCL are exposed to either the RCL or the consuming app under the prefix _content/{LIBRARY NAME}/. Por ejemplo, una biblioteca denominada Razor. class. lib da como resultado una ruta de acceso al contenido estático en _content/Razor.Class.Lib/.For example, a library named Razor.Class.Lib results in a path to static content at _content/Razor.Class.Lib/. Al generar un paquete de NuGet y el nombre de ensamblado no es el mismo que el identificador de paquete, use el identificador de paquete para {LIBRARY NAME}.When producing a NuGet package and the assembly name isn't the same as the package ID, use the package ID for {LIBRARY NAME}.

La aplicación de consumo hace referencia a los recursos estáticos proporcionados por la biblioteca con <script>, <style>, <img>y otras etiquetas HTML.The consuming app references static assets provided by the library with <script>, <style>, <img>, and other HTML tags. La aplicación de consumo debe tener habilitada la compatibilidad con archivos estáticos en Startup.Configure:The consuming app must have static file support enabled in Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    ...

    app.UseStaticFiles();

    ...
}

Al ejecutar la aplicación de consumo desde la salida de la compilación (dotnet run), los activos web estáticos están habilitados de forma predeterminada en el entorno de desarrollo.When running the consuming app from build output (dotnet run), static web assets are enabled by default in the Development environment. Para admitir recursos en otros entornos cuando se ejecutan desde la salida de la compilación, llame a UseStaticWebAssets en el generador de hosts en Program.CS:To support assets in other environments when running from build output, call UseStaticWebAssets on the host builder in Program.cs:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStaticWebAssets();
                webBuilder.UseStartup<Startup>();
            });
}

No es necesario llamar a UseStaticWebAssets cuando se ejecuta una aplicación desde la salida publicada (dotnet publish).Calling UseStaticWebAssets isn't required when running an app from published output (dotnet publish).

Flujo de desarrollo de varios proyectosMulti-project development flow

Cuando se ejecuta la aplicación de consumo:When the consuming app runs:

  • Los recursos de RCL permanecen en sus carpetas originales.The assets in the RCL stay in their original folders. Los recursos no se mueven a la aplicación de consumo.The assets aren't moved to the consuming app.
  • Cualquier cambio dentro de la carpeta wwwroot de RCL se refleja en la aplicación de consumo después de que se vuelva a generar RCL y sin volver a generar la aplicación de consumo.Any change within the RCL's wwwroot folder is reflected in the consuming app after the RCL is rebuilt and without rebuilding the consuming app.

Cuando se compila el RCL, se genera un manifiesto que describe las ubicaciones de los recursos web estáticos.When the RCL is built, a manifest is produced that describes the static web asset locations. La aplicación consumidora lee el manifiesto en tiempo de ejecución para consumir los recursos de los proyectos y paquetes a los que se hace referencia.The consuming app reads the manifest at runtime to consume the assets from referenced projects and packages. Cuando se agrega un nuevo recurso a un RCL, se debe volver a generar el RCL para actualizar el manifiesto antes de que una aplicación de consumo pueda acceder al nuevo recurso.When a new asset is added to an RCL, the RCL must be rebuilt to update its manifest before a consuming app can access the new asset.

PublicarPublish

Cuando se publica la aplicación, los recursos complementarios de todos los proyectos y paquetes a los que se hace referencia se copian en la carpeta wwwroot de la aplicación publicada en _content/{LIBRARY NAME}/.When the app is published, the companion assets from all referenced projects and packages are copied into the wwwroot folder of the published app under _content/{LIBRARY NAME}/.

Las vistas, páginas, controladores, modelos de páginas, componentes de Razor, componentes de vistay modelos de datos de Razor se pueden integrar en una biblioteca de clases de Razor (RCL).Razor views, pages, controllers, page models, Razor components, View components, and data models can be built into a Razor class library (RCL). Las RCL se pueden empaquetar y reutilizar.The RCL can be packaged and reused. Las aplicaciones pueden incluir la RCL y reemplazar las vistas y páginas que contienen.Applications can include the RCL and override the views and pages it contains. Cuando existe una vista, vista parcial o página de Razor tanto en la aplicación web como en la RCL, tendrá prioridad el marcado de Razor (archivo .cshtml) de la aplicación web.When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence.

Vea o descargue el código de ejemplo (cómo descargarlo)View or download sample code (how to download)

Crear una biblioteca de clases que contenga interfaz de usuario de RazorCreate a class library containing Razor UI

  • En el menú Archivo de Visual Studio, seleccione Nuevo > Proyecto.From the Visual Studio File menu, select New > Project.
  • Seleccione Aplicación web ASP.NET Core.Select ASP.NET Core Web Application.
  • Asigne un nombre a la biblioteca (por ejemplo, "RazorClassLib") > Aceptar.Name the library (for example, "RazorClassLib") > OK. Para evitar un conflicto de nombres de archivo con la biblioteca de vistas generada, asegúrese de que el nombre de la biblioteca no acaba en .Views.To avoid a file name collision with the generated view library, ensure the library name doesn't end in .Views.
  • Confirme que ASP.NET Core 2.1 o una versión posterior está seleccionado.Verify ASP.NET Core 2.1 or later is selected.
  • Seleccione biblioteca de clases de Razor > Aceptar.Select Razor Class Library > OK.

Un RCL tiene el siguiente archivo de proyecto:An RCL has the following project file:

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  </ItemGroup>

</Project>

Agregue archivos de Razor a la RCL.Add Razor files to the RCL.

Las plantillas ASP.NET Core suponen que el contenido de RCL se encuentra en la carpeta áreas .The ASP.NET Core templates assume the RCL content is in the Areas folder. Consulte diseño de páginas de RCL para crear un RCL que exponga contenido en ~/Pages en lugar de ~/Areas/Pages.See RCL Pages layout to create an RCL that exposes content in ~/Pages rather than ~/Areas/Pages.

Contenido de RCL de referenciaReference RCL content

Los siguientes elementos pueden hacer referencia a la RCL:The RCL can be referenced by:

Tutorial: creación de un proyecto de RCL y uso de un proyecto de Razor PagesWalkthrough: Create an RCL project and use from a Razor Pages project

En lugar de crearlo, puede descargar el proyecto completo y comprobarlo.You can download the complete project and test it rather than creating it. La descarga de ejemplo contiene más código y vínculos que hacen que el proyecto sea fácil de comprobar.The sample download contains additional code and links that make the project easy to test. Puede dejar sus comentarios en este problema de GitHub sobre las descargas de ejemplo en comparación con las instrucciones paso a paso.You can leave feedback in this GitHub issue with your comments on download samples versus step-by-step instructions.

Comprobar la aplicación de descargaTest the download app

Si no ha descargado la aplicación final y prefiere crear el proyecto de tutorial, omita este paso y vaya a la siguiente sección.If you haven't downloaded the completed app and would rather create the walkthrough project, skip to the next section.

Abra el archivo .sln en Visual Studio.Open the .sln file in Visual Studio. Ejecute la aplicación.Run the app.

Siga las instrucciones de Probar WebApp1.Follow the instructions in Test WebApp1

Creación de un RCLCreate an RCL

En esta sección, se crea un RCL.In this section, an RCL is created. y se agregarán a ella archivos de Razor.Razor files are added to the RCL.

Cree el proyecto de RCL:Create the RCL project:

  • En el menú Archivo de Visual Studio, seleccione Nuevo > Proyecto.From the Visual Studio File menu, select New > Project.
  • Seleccione Aplicación web ASP.NET Core.Select ASP.NET Core Web Application.
  • Asigne a la aplicación el nombre RazorUIClassLib > Aceptar.Name the app RazorUIClassLib > OK.
  • Confirme que ASP.NET Core 2.1 o una versión posterior está seleccionado.Verify ASP.NET Core 2.1 or later is selected.
  • Seleccione biblioteca de clases de Razor > Aceptar.Select Razor Class Library > OK.
  • Agregue un archivo de vista parcial de Razor denominado RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml.Add a Razor partial view file named RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml.

Agregar archivos de Razor y carpetas al proyectoAdd Razor files and folders to the project

  • Reemplace el marcado de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml por el siguiente código:Replace the markup in RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml with the following code:

    <h3>_Message.cshtml partial view.</h3>
    
    <p>RazorUIClassLib\Areas\MyFeature\Pages\Shared\_Message.cshtml</p>
    
  • Reemplace el marcado de RazorUIClassLib/Areas/MyFeature/Pages/Page1.cshtml por el siguiente código:Replace the markup in RazorUIClassLib/Areas/MyFeature/Pages/Page1.cshtml with the following code:

    @page
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    
    <h2>Hello from a Razor UI class library!</h2>
    <p> From  RazorUIClassLib\Areas\MyFeature\Pages\Page1.cshtml</p>
    
    <partial name="_Message" />
    

    Se necesita @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers para usar la vista parcial (<partial name="_Message" />).@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers is required to use the partial view (<partial name="_Message" />). En lugar de incluir la directiva @addTagHelper, puede agregar un archivo _ViewImports.cshtml.Rather than including the @addTagHelper directive, you can add a _ViewImports.cshtml file. Por ejemplo:For example:

    dotnet new viewimports -o RazorUIClassLib/Areas/MyFeature/Pages
    

    Para obtener más información sobre _ViewImports. cshtml, vea importar directivas compartidas .For more information on _ViewImports.cshtml, see Importing Shared Directives

  • Compile la biblioteca de clases para confirmar que no hay ningún error de compilador:Build the class library to verify there are no compiler errors:

    dotnet build RazorUIClassLib
    

El resultado de la compilación contiene RazorUIClassLib.dll y RazorUIClassLib.Views.dll.The build output contains RazorUIClassLib.dll and RazorUIClassLib.Views.dll. RazorUIClassLib.Views.dll incluye el contenido de Razor compilado.RazorUIClassLib.Views.dll contains the compiled Razor content.

Usar la biblioteca de interfaz de usuario de Razor desde un proyecto de páginas de RazorUse the Razor UI library from a Razor Pages project

Cree la aplicación web de páginas de Razor:Create the Razor Pages web app:

  • En Explorador de soluciones, haga clic con el botón secundario en la solución > Agregar >nuevo proyecto.From Solution Explorer, right-click the solution > Add > New Project.

  • Seleccione Aplicación web ASP.NET Core.Select ASP.NET Core Web Application.

  • Denomine la aplicación WebApp1.Name the app WebApp1.

  • Confirme que ASP.NET Core 2.1 o una versión posterior está seleccionado.Verify ASP.NET Core 2.1 or later is selected.

  • Seleccione aplicación Web > Aceptar.Select Web Application > OK.

  • En el Explorador de soluciones, haga clic con el botón derecho en WebApp1 y seleccione Establecer como proyecto de inicio.From Solution Explorer, right-click on WebApp1 and select Set as StartUp Project.

  • En Explorador de soluciones, haga clic con el botón derecho en WebApp1 y seleccione dependencias de compilación > dependencias del proyecto.From Solution Explorer, right-click on WebApp1 and select Build Dependencies > Project Dependencies.

  • Marque RazorUIClassLib como dependencia de WebApp1.Check RazorUIClassLib as a dependency of WebApp1.

  • En Explorador de soluciones, haga clic con el botón derecho en WebApp1 y seleccione Agregar referenciade >.From Solution Explorer, right-click on WebApp1 and select Add > Reference.

  • En el cuadro de diálogo Administrador de referencias , active RazorUIClassLib > Aceptar.In the Reference Manager dialog, check RazorUIClassLib > OK.

Ejecute la aplicación.Run the app.

Probar WebApp1Test WebApp1

Vaya a /MyFeature/Page1 para comprobar que la biblioteca de clases de la interfaz de usuario de Razor está en uso.Browse to /MyFeature/Page1 to verify that the Razor UI class library is in use.

Reemplazar vistas, vistas parciales y páginasOverride views, partial views, and pages

Cuando existe una vista, vista parcial o página de Razor tanto en la aplicación web como en la RCL, tendrá prioridad el marcado de Razor (archivo .cshtml) de la aplicación web.When a view, partial view, or Razor Page is found in both the web app and the RCL, the Razor markup (.cshtml file) in the web app takes precedence. Por ejemplo, agregue WebApp1/areas/mi Feature/pages/Page1. cshtml a WebApp1 y Page1 en WebApp1 tendrá prioridad sobre PÁGINA1 en RCL.For example, add WebApp1/Areas/MyFeature/Pages/Page1.cshtml to WebApp1, and Page1 in the WebApp1 will take precedence over Page1 in the RCL.

En la descarga de ejemplo, cambie el nombre WebApp1/Areas/MyFeature2 por WebApp1/Areas/MyFeature para comprobar la prioridad.In the sample download, rename WebApp1/Areas/MyFeature2 to WebApp1/Areas/MyFeature to test precedence.

Copie la vista parcial RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml en WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml.Copy the RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml partial view to WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Actualice el marcado para señalar la nueva ubicación.Update the markup to indicate the new location. Compile y ejecute la aplicación para comprobar si se está usando la versión de la vista parcial de la aplicación.Build and run the app to verify the app's version of the partial is being used.

Diseño de páginas RCLRCL Pages layout

Para hacer referencia al contenido de RCL como si formara parte de la carpeta páginas de la aplicación Web, cree el proyecto RCL con la siguiente estructura de archivos:To reference RCL content as though it is part of the web app's Pages folder, create the RCL project with the following file structure:

  • RazorUIClassLib/páginasRazorUIClassLib/Pages
  • RazorUIClassLib/páginas/compartidoRazorUIClassLib/Pages/Shared

Supongamos que RazorUIClassLib/pages/Shared contiene dos archivos parciales: _Header. cshtml y _Footer. cshtml.Suppose RazorUIClassLib/Pages/Shared contains two partial files: _Header.cshtml and _Footer.cshtml. Las etiquetas de <partial> se pueden agregar al archivo _Layout. cshtml :The <partial> tags could be added to _Layout.cshtml file:

<body>
  <partial name="_Header">
  @RenderBody()
  <partial name="_Footer">
</body>

Recursos adicionalesAdditional resources