Creación de una interfaz de usuario reutilizable con 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 y modelos de página de Razor, los componentes de Razor, los componentes de vista y los modelos de datos 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. Si existe una vista,una vista parcial o una página de Razor tanto en la aplicación web como en la RCL, tiene 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)

Creación de una biblioteca de clases que contenga interfaz de usuario de RazorCreate a class library containing Razor UI

  • En Visual Studio, seleccione Crear un proyecto nuevo.From Visual Studio select Create new a new project.
  • Seleccione Biblioteca de clases de Razor > Siguiente.Select Razor Class Library > Next.
  • Asigne un nombre a la biblioteca (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 Admitir páginas y vistas si necesita admitir vistas.Select Support pages and views if you need to support views. Solo se admite Razor Pages de forma predeterminada.By default, only Razor Pages are supported. Seleccione Crear.Select Create.

De forma predeterminada, la plantilla de la biblioteca de clases de Razor (RCL) usa el desarrollo de componentes de Razor.The Razor class library (RCL) template defaults to Razor component development by default. La opción Admitir páginas y vistas proporciona compatibilidad con 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 de ASP.NET Core dan por sentado que el contenido de la RCL se encuentra en la carpeta Áreas.The ASP.NET Core templates assume the RCL content is in the Areas folder. Consulte la sección Diseño de páginas de RCL para crear una RCL que exponga contenido en ~/Pages y no en ~/Areas/Pages.See RCL Pages layout to create an RCL that exposes content in ~/Pages rather than ~/Areas/Pages.

Referencias al contenido de la RCLReference 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

Si existe una vista,una vista parcial o una página de Razor tanto en la aplicación web como en la RCL, tiene 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, si agrega WebApp1/Areas/MyFeature/Pages/Page1.cshtml a WebApp1, Page1 en WebApp1 prevalecerá sobre Page1 en la biblioteca de clases de Razor.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 de RCLRCL Pages layout

Para hacer referencia al contenido de la RCL como si formara parte de la carpeta Pages 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/PagesRazorUIClassLib/Pages
  • RazorUIClassLib/Pages/SharedRazorUIClassLib/Pages/Shared

Imagine 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. En ese caso, se podrían agregar etiquetas <partial> 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 una RCL con recursos estáticosCreate an RCL with static assets

Una RCL puede requerir recursos estáticos complementarios a los que puede hacer referencia la RCL o la aplicación de consumo de la 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 bibliotecas de clases de Razor que incluyan 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 una RCL, cree una carpeta wwwroot en la biblioteca de clases e incluya en ella los archivos necesarios.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 una 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.

Use el comando dotnet pack en vez de la versión de NuGet.exe nuget pack.Use the dotnet pack command rather than the NuGet.exe version nuget pack.

Exclusión de 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 del 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 la RCL publicada: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 archivos TypeScript en una 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 la salida 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 del 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 ResolveCurrentProjectStaticWebAssets; para ello, agregue el siguiente destino dentro de un objeto PropertyGroup en el archivo del 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 la RCL se exponen a la 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 produce 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 NuGet, si el nombre del ensamblado no es igual que el del identificador del 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 al ejecutar la aplicación 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 si 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

Al ejecutar la aplicación de consumo:When the consuming app runs:

  • Los recursos de la biblioteca de clases de Razor 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 la RCL se refleja en la aplicación de consumo después de que se vuelva a compilar la RCL y sin tener que recompilar 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 la biblioteca de clases de Razor, 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 de consumo 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 una RCL, esta se debe recompilar 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 y modelos de página de Razor, los componentes de Razor, los componentes de vista y los modelos de datos 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. Si existe una vista,una vista parcial o una página de Razor tanto en la aplicación web como en la RCL, tiene 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)

Creación de 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 de 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.

Una 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 de ASP.NET Core dan por sentado que el contenido de la RCL se encuentra en la carpeta Áreas.The ASP.NET Core templates assume the RCL content is in the Areas folder. Consulte la sección Diseño de páginas de RCL para crear una RCL que exponga contenido en ~/Pages y no en ~/Areas/Pages.See RCL Pages layout to create an RCL that exposes content in ~/Pages rather than ~/Areas/Pages.

Referencias al contenido de la RCLReference RCL content

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

Tutorial: Creación y uso de un proyecto de RCL desde 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. Ejecutar la aplicación.Run the app.

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

Creación de una RCLCreate an RCL

En esta sección, se creará una RCLIn 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 de 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.

Adición de archivos y carpetas de Razor 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, consulte la sección 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.

Uso de la biblioteca de interfaz de usuario de Razor desde un proyecto de Razor PagesUse 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 el Explorador de soluciones, haga clic con el botón derecho en la solución > Agregar > Nuevo proyecto.From Solution Explorer, right-click the solution > Add > New Project.

  • Seleccione Aplicación web de 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 el 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 el Explorador de soluciones, haga clic con el botón derecho en WebApp1 y seleccione Agregar > Referencia.From Solution Explorer, right-click on WebApp1 and select Add > Reference.

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

Ejecutar 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

Si existe una vista,una vista parcial o una página de Razor tanto en la aplicación web como en la RCL, tiene 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, si agrega WebApp1/Areas/MyFeature/Pages/Page1.cshtml a WebApp1, Page1 en WebApp1 prevalecerá sobre Page1 en la biblioteca de clases de Razor.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 de RCLRCL Pages layout

Para hacer referencia al contenido de la RCL como si formara parte de la carpeta Pages 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/PagesRazorUIClassLib/Pages
  • RazorUIClassLib/Pages/SharedRazorUIClassLib/Pages/Shared

Imagine 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. En ese caso, se podrían agregar etiquetas <partial> 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