Criar interface do usuário reutilizável usando o projeto de biblioteca de classes Razor no ASP.NET Core

De Rick Anderson

Modos de exibição do Razor, páginas, controladores, modelos de página, Razor componentes, Componentes de exibição e modelos de dados podem ser inseridos em uma RCL (biblioteca de classes Razor). A RCL pode ser e empacotada e reutilizada. Os aplicativos podem incluir a RCL e substituir as exibições e as páginas que ela contém. Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência.

Para obter informações sobre como integrar o npm e o webpack ao processo de build de uma Biblioteca de Classes Razor, consulte Criar ativos web cliente para sua Biblioteca de Classes Razor.

Criar uma biblioteca de classes contendo a interface do usuário do Razor

  • No Visual Studio, selecione Criar um projeto.
  • Selecione Biblioteca de Classes Razor>Avançar.
  • Dê um nome à biblioteca (por exemplo, "RazorClassLib"), >Criar. Para evitar uma colisão de nome de arquivo com a biblioteca de exibição gerada, verifique se o nome da biblioteca não termina em .Views.
  • Selecione Suporte a páginas e exibições se precisar que a biblioteca contenha páginas e/ou exibições. Por padrão, somente componentes Razor é compatível. Selecione Criar.

O modelo de RCL (biblioteca de classes) Razor usa o desenvolvimento de componentes Razor por padrão. A opção Páginas e exibições de suporte dá suporte a páginas e exibições. Para obter mais informações sobre o suporte à RCL em Blazor, confira Consumir componentes do ASP.NET Core Razor de uma biblioteca de classes (RCL) Razor.

Adicione arquivos Razor na RCL.

Os modelos de ASP.NET Core pressupõem que o conteúdo RCL esteja na pasta Areas. Veja o layout da RCL Pages abaixo para criar uma RCL que expõe o conteúdo no ~/Pages em vez de ~/Areas/Pages.

Referenciar conteúdo RCL

A RCL pode ser referenciada por:

Substituir exibições, exibições parciais e páginas

Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência. Por exemplo, adicione WebApp1/Areas/MyFeature/Pages/Page1.cshtml ao WebApp1 e Page1 no WebApp1 terá precedência sobre Page1 na RCL.

No download de exemplo, renomeie WebApp1/Areas/MyFeature2 como WebApp1/Areas/MyFeature para testar a precedência.

Copie a exibição parcial de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml para WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Atualize a marcação para indicar o novo local. Crie e execute o aplicativo para verificar se a versão da parcial do aplicativo está sendo usada.

Se a RCL usar Razor Pages, habilite os serviços e os pontos de extremidade do Razor Pages no aplicativo de hospedagem:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Layout da RCL Pages

Para fazer referência ao conteúdo da RCL como se fosse parte da pasta Pages do aplicativo Web, crie o projeto da RCL com a seguinte estrutura de arquivos:

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Suponha que RazorUIClassLib/Pages/Shared contenha dois arquivos parciais: _Header.cshtml e _Footer.cshtml. As marcas <partial> podem ser adicionadas ao arquivo _Layout.cshtml:

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

Adicione o arquivo _ViewStart.cshtml à pasta do Pages projeto RCL para usar o arquivo _Layout.cshtml do aplicativo Web de host:

@{
    Layout = "_Layout";
}

Criar uma RCL com ativos estáticos

Uma RCL pode exigir ativos estáticos complementares que podem ser referenciados pela RCL ou pelo aplicativo de consumo da RCL. O ASP.NET Core permite a criação de RCLs que incluem ativos estáticos disponíveis para um aplicativo de consumo.

Para incluir ativos complementares como parte de uma RCL, crie uma pasta wwwroot na biblioteca de classes e inclua todos os arquivos necessários nessa pasta.

Ao empacotar uma RCL, todos os ativos complementares na pasta wwwroot são incluídos automaticamente no pacote.

Use o comando dotnet pack em vez da versão nuget pack do NuGet.exe.

Adicionar ativos Web do cliente ao processo de build

A integração de ativos Web do cliente ao pipeline de build não é trivial. Confira Criar ativos da Web do cliente para a sua biblioteca de classes Razor para obter mais informações.

Excluir ativos estáticos

Para excluir ativos estáticos, adicione o caminho de exclusão desejado ao grupo de propriedades $(DefaultItemExcludes) no arquivo de projeto. Separe entradas com ponto e vírgula (;).

No exemplo a seguir, a folha de estilos lib.css na pasta wwwroot não é considerada um ativo estático e não está incluída na RCL publicada:

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

Integração com Typescript

Para incluir arquivos TypeScript em uma RCL:

  1. Faça referência ao pacote NuGet Microsoft.TypeScript.MSBuild no projeto.

    Observação

    Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

  2. Coloque os arquivos TypeScript (.ts) fora da pasta wwwroot. Por exemplo, coloque os arquivos em uma pasta Client.

  3. Configure a saída de build do TypeScript para a pasta wwwroot. Defina a propriedade TypescriptOutDir dentro de um PropertyGroup no arquivo de projeto:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Inclua o destino TypeScript como uma dependência do destino PrepareForBuildDependsOn adicionando o seguinte destino dentro de um PropertyGroup no arquivo de projeto:

    <PrepareForBuildDependsOn>
      CompileTypeScript;
      GetTypeScriptOutputForPublishing;$(PrepareForBuildDependsOn)
    </PrepareForBuildDependsOn>
    

Consumir conteúdo de uma RCL referenciada

Os arquivos incluídos na pasta wwwroot da RCL são expostos à RCL ou ao aplicativo de consumo no prefixo _content/{PACKAGE ID}/. Por exemplo, uma biblioteca com um nome de assembly de Razor.Class.Lib e sem um <PackageId> especificado em seu arquivo de projeto resulta em um caminho para o conteúdo estático em _content/Razor.Class.Lib/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID}.

O aplicativo de consumo faz referência a ativos estáticos fornecidos pela biblioteca com <script>, <style>, <img> e outras marcas HTML. O aplicativo de consumo deve ter suporte a arquivos estáticos habilitado em:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Ao executar o aplicativo de consumo da saída de build (dotnet run), os ativos da Web estáticos são habilitados por padrão no ambiente de desenvolvimento. Para dar suporte a ativos em outros ambientes ao executar a partir da saída de build, chame UseStaticWebAssets no construtor de host em Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseWebRoot("wwwroot");
builder.WebHost.UseStaticWebAssets();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

A chamada de UseStaticWebAssets não é necessária ao executar um aplicativo da saída publicada (dotnet publish).

Fluxo de desenvolvimento de vários projetos

Quando o aplicativo de consumo é executado:

  • Os ativos na RCL permanecem em suas pastas originais. Os ativos não são movidos para o aplicativo de consumo.
  • Qualquer alteração na pasta wwwroot da RCL é refletida no aplicativo de consumo depois que a RCL é reconstruída e sem recriar o aplicativo de consumo.

Quando a RCL é criada, um manifesto é produzido que descreve os locais de ativos da Web estáticos. O aplicativo de consumo lê o manifesto em runtime para consumir os ativos de projetos e pacotes referenciados. Quando um novo ativo é adicionado a uma RCL, a RCL deve ser recriada para atualizar seu manifesto antes que um aplicativo de consumo possa acessar o novo ativo.

Publicação

Quando o aplicativo é publicado, os ativos complementares de todos os projetos e pacotes referenciados são copiados para a pasta wwwroot do aplicativo publicado em _content/{PACKAGE ID}/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID} ao examinar a pasta wwwroot dos ativos publicados.

Recursos adicionais

Modos de exibição do Razor, páginas, controladores, modelos de página, Razor componentes, Componentes de exibição e modelos de dados podem ser inseridos em uma RCL (biblioteca de classes Razor). A RCL pode ser e empacotada e reutilizada. Os aplicativos podem incluir a RCL e substituir as exibições e as páginas que ela contém. Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência.

Para obter informações sobre como integrar o npm e o webpack ao processo de build de uma Biblioteca de Classes Razor, consulte Criar ativos web cliente para sua Biblioteca de Classes Razor.

Criar uma biblioteca de classes contendo a interface do usuário do Razor

  • No Visual Studio, selecione Criar um projeto.
  • Selecione Biblioteca de Classes Razor>Avançar.
  • Dê um nome à biblioteca (por exemplo, "RazorClassLib"), >Criar. Para evitar uma colisão de nome de arquivo com a biblioteca de exibição gerada, verifique se o nome da biblioteca não termina em .Views.
  • Selecione Páginas e exibições de suporte se precisar dar suporte a exibições. Por padrão, somente Razor Pages é compatível. Selecione Criar.

O modelo de RCL (biblioteca de classes) Razor usa o desenvolvimento de componentes Razor por padrão. A opção Páginas e exibições de suporte dá suporte a páginas e exibições.

Adicione arquivos Razor na RCL.

Os modelos de ASP.NET Core pressupõem que o conteúdo RCL esteja na pasta Areas. Veja o layout da RCL Pages abaixo para criar uma RCL que expõe o conteúdo no ~/Pages em vez de ~/Areas/Pages.

Referenciar conteúdo RCL

A RCL pode ser referenciada por:

Substituir exibições, exibições parciais e páginas

Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência. Por exemplo, adicione WebApp1/Areas/MyFeature/Pages/Page1.cshtml ao WebApp1 e Page1 no WebApp1 terá precedência sobre Page1 na RCL.

No download de exemplo, renomeie WebApp1/Areas/MyFeature2 como WebApp1/Areas/MyFeature para testar a precedência.

Copie a exibição parcial de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml para WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Atualize a marcação para indicar o novo local. Crie e execute o aplicativo para verificar se a versão da parcial do aplicativo está sendo usada.

Se a RCL usar Razor Pages, habilite os serviços e os pontos de extremidade do Razor Pages no aplicativo de hospedagem:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Layout da RCL Pages

Para fazer referência ao conteúdo da RCL como se fosse parte da pasta Pages do aplicativo Web, crie o projeto da RCL com a seguinte estrutura de arquivos:

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Suponha que RazorUIClassLib/Pages/Shared contenha dois arquivos parciais: _Header.cshtml e _Footer.cshtml. As marcas <partial> podem ser adicionadas ao arquivo _Layout.cshtml:

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

Adicione o arquivo _ViewStart.cshtml à pasta do Pages projeto RCL para usar o arquivo _Layout.cshtml do aplicativo Web de host:

@{
    Layout = "_Layout";
}

Criar uma RCL com ativos estáticos

Uma RCL pode exigir ativos estáticos complementares que podem ser referenciados pela RCL ou pelo aplicativo de consumo da RCL. O ASP.NET Core permite a criação de RCLs que incluem ativos estáticos disponíveis para um aplicativo de consumo.

Para incluir ativos complementares como parte de uma RCL, crie uma pasta wwwroot na biblioteca de classes e inclua todos os arquivos necessários nessa pasta.

Ao empacotar uma RCL, todos os ativos complementares na pasta wwwroot são incluídos automaticamente no pacote.

Use o comando dotnet pack em vez da versão nuget pack do NuGet.exe.

Excluir ativos estáticos

Para excluir ativos estáticos, adicione o caminho de exclusão desejado ao grupo de propriedades $(DefaultItemExcludes) no arquivo de projeto. Separe entradas com ponto e vírgula (;).

No exemplo a seguir, a folha de estilos lib.css na pasta wwwroot não é considerada um ativo estático e não está incluída na RCL publicada:

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

Integração com Typescript

Para incluir arquivos TypeScript em uma RCL:

  1. Faça referência ao pacote NuGet Microsoft.TypeScript.MSBuild no projeto.

    Observação

    Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

  2. Coloque os arquivos TypeScript (.ts) fora da pasta wwwroot. Por exemplo, coloque os arquivos em uma pasta Client.

  3. Configure a saída de build do TypeScript para a pasta wwwroot. Defina a propriedade TypescriptOutDir dentro de um PropertyGroup no arquivo de projeto:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Inclua o destino TypeScript como uma dependência do destino PrepareForBuildDependsOn adicionando o seguinte destino dentro de um PropertyGroup no arquivo de projeto:

    <PrepareForBuildDependsOn>
      CompileTypeScript;
      GetTypeScriptOutputForPublishing;$(PrepareForBuildDependsOn)
    </PrepareForBuildDependsOn>
    

Consumir conteúdo de uma RCL referenciada

Os arquivos incluídos na pasta wwwroot da RCL são expostos à RCL ou ao aplicativo de consumo no prefixo _content/{PACKAGE ID}/. Por exemplo, uma biblioteca com um nome de assembly de Razor.Class.Lib e sem um <PackageId> especificado em seu arquivo de projeto resulta em um caminho para o conteúdo estático em _content/Razor.Class.Lib/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID}.

O aplicativo de consumo faz referência a ativos estáticos fornecidos pela biblioteca com <script>, <style>, <img> e outras marcas HTML. O aplicativo de consumo deve ter suporte a arquivos estáticos habilitado em:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();
app.Run();

Ao executar o aplicativo de consumo da saída de build (dotnet run), os ativos da Web estáticos são habilitados por padrão no ambiente de desenvolvimento. Para dar suporte a ativos em outros ambientes ao executar a partir da saída de build, chame UseStaticWebAssets no construtor de host em Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseWebRoot("wwwroot").UseStaticWebAssets();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Observação: o .NET 6 requer apenas a chamada para builder.WebHost.UseWebRoot("wwwroot").UseStaticWebAssets. Saiba mais neste tópico do GitHub.

A chamada de UseStaticWebAssets não é necessária ao executar um aplicativo da saída publicada (dotnet publish).

Fluxo de desenvolvimento de vários projetos

Quando o aplicativo de consumo é executado:

  • Os ativos na RCL permanecem em suas pastas originais. Os ativos não são movidos para o aplicativo de consumo.
  • Qualquer alteração na pasta wwwroot da RCL é refletida no aplicativo de consumo depois que a RCL é reconstruída e sem recriar o aplicativo de consumo.

Quando a RCL é criada, um manifesto é produzido que descreve os locais de ativos da Web estáticos. O aplicativo de consumo lê o manifesto em runtime para consumir os ativos de projetos e pacotes referenciados. Quando um novo ativo é adicionado a uma RCL, a RCL deve ser recriada para atualizar seu manifesto antes que um aplicativo de consumo possa acessar o novo ativo.

Publicação

Quando o aplicativo é publicado, os ativos complementares de todos os projetos e pacotes referenciados são copiados para a pasta wwwroot do aplicativo publicado em _content/{PACKAGE ID}/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID} ao examinar a pasta wwwroot dos ativos publicados.

Recursos adicionais

Modos de exibição do Razor, páginas, controladores, modelos de página, Razor componentes, Componentes de exibição e modelos de dados podem ser inseridos em uma RCL (biblioteca de classes Razor). A RCL pode ser e empacotada e reutilizada. Os aplicativos podem incluir a RCL e substituir as exibições e as páginas que ela contém. Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência.

Exibir ou baixar código de exemplo (como baixar)

Criar uma biblioteca de classes contendo a interface do usuário do Razor

  • No Visual Studio, selecione Criar um projeto.
  • Selecione Biblioteca de Classes Razor>Avançar.
  • Dê um nome à biblioteca (por exemplo, "RazorClassLib"), >Criar>Avançar. Para evitar uma colisão de nome de arquivo com a biblioteca de exibição gerada, verifique se o nome da biblioteca não termina em .Views.
  • Selecione a Estrutura de destino. Verifique ☑ Páginas e exibições de suporte para dar suporte a exibições. Por padrão, somente componentes Razor é compatível. Selecione Criar.

O modelo de RCL (biblioteca de classes) Razor usa o desenvolvimento de componentes Razor por padrão. A opção Páginas e exibições de suporte dá suporte a páginas e exibições.

Adicione arquivos Razor na RCL.

Os modelos de ASP.NET Core pressupõem que o conteúdo RCL esteja na pasta Areas. Veja o layout da RCL Pages para criar uma RCL que expõe o conteúdo no ~/Pages em vez de ~/Areas/Pages.

Referenciar conteúdo RCL

A RCL pode ser referenciada por:

Substituir exibições, exibições parciais e páginas

Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência. Por exemplo, adicione WebApp1/Areas/MyFeature/Pages/Page1.cshtml ao WebApp1 e Page1 no WebApp1 terá precedência sobre Page1 na RCL.

No download de exemplo, renomeie WebApp1/Areas/MyFeature2 como WebApp1/Areas/MyFeature para testar a precedência.

Copie a exibição parcial de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml para WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Atualize a marcação para indicar o novo local. Crie e execute o aplicativo para verificar se a versão da parcial do aplicativo está sendo usada.

Layout da RCL Pages

Para fazer referência ao conteúdo da RCL como se fosse parte da pasta Pages do aplicativo Web, crie o projeto da RCL com a seguinte estrutura de arquivos:

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Suponha que RazorUIClassLib/Pages/Shared contenha dois arquivos parciais: _Header.cshtml e _Footer.cshtml. As marcas <partial> podem ser adicionadas ao arquivo _Layout.cshtml:

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

Adicione o arquivo _ViewStart.cshtml à pasta do Pages projeto RCL para usar o arquivo _Layout.cshtml do aplicativo Web de host:

@{
    Layout = "_Layout";
}

Criar uma RCL com ativos estáticos

Uma RCL pode exigir ativos estáticos complementares que podem ser referenciados pela RCL ou pelo aplicativo de consumo da RCL. O ASP.NET Core permite a criação de RCLs que incluem ativos estáticos disponíveis para um aplicativo de consumo.

Para incluir ativos complementares como parte de uma RCL, crie uma pasta wwwroot na biblioteca de classes e inclua todos os arquivos necessários nessa pasta.

Ao empacotar uma RCL, todos os ativos complementares na pasta wwwroot são incluídos automaticamente no pacote.

Use o comando dotnet pack em vez da versão nuget pack do NuGet.exe.

Excluir ativos estáticos

Para excluir ativos estáticos, adicione o caminho de exclusão desejado ao grupo de propriedades $(DefaultItemExcludes) no arquivo de projeto. Separe entradas com ponto e vírgula (;).

No exemplo a seguir, a folha de estilos lib.css na pasta wwwroot não é considerada um ativo estático e não está incluída na RCL publicada:

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

Integração com Typescript

Para incluir arquivos TypeScript em uma RCL:

  1. Faça referência ao pacote NuGet Microsoft.TypeScript.MSBuild no projeto.

    Observação

    Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

  2. Coloque os arquivos TypeScript (.ts) fora da pasta wwwroot. Por exemplo, coloque os arquivos em uma pasta Client.

  3. Configure a saída de build do TypeScript para a pasta wwwroot. Defina a propriedade TypescriptOutDir dentro de um PropertyGroup no arquivo de projeto:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Inclua o destino TypeScript como uma dependência do destino ResolveCurrentProjectStaticWebAssets adicionando o seguinte destino dentro de um PropertyGroup no arquivo de projeto:

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

Consumir conteúdo de uma RCL referenciada

Os arquivos incluídos na pasta wwwroot da RCL são expostos à RCL ou ao aplicativo de consumo no prefixo _content/{PACKAGE ID}/. Por exemplo, uma biblioteca com um nome de assembly de Razor.Class.Lib e sem um <PackageId> especificado em seu arquivo de projeto resulta em um caminho para o conteúdo estático em _content/Razor.Class.Lib/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID}.

O aplicativo de consumo faz referência a ativos estáticos fornecidos pela biblioteca com <script>, <style>, <img> e outras marcas HTML. O aplicativo de consumo deve ter suporte a arquivos estáticos habilitado em Startup.Configure:

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

    app.UseStaticFiles();

    ...
}

Ao executar o aplicativo de consumo da saída de build (dotnet run), os ativos da Web estáticos são habilitados por padrão no ambiente de desenvolvimento. Para dar suporte a ativos em outros ambientes ao executar a partir da saída de build, chame UseStaticWebAssets no construtor de host em 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>();
            });
}

A chamada de UseStaticWebAssets não é necessária ao executar um aplicativo da saída publicada (dotnet publish).

Fluxo de desenvolvimento de vários projetos

Quando o aplicativo de consumo é executado:

  • Os ativos na RCL permanecem em suas pastas originais. Os ativos não são movidos para o aplicativo de consumo.
  • Qualquer alteração na pasta wwwroot da RCL é refletida no aplicativo de consumo depois que a RCL é reconstruída e sem recriar o aplicativo de consumo.

Quando a RCL é criada, um manifesto é produzido que descreve os locais de ativos da Web estáticos. O aplicativo de consumo lê o manifesto em runtime para consumir os ativos de projetos e pacotes referenciados. Quando um novo ativo é adicionado a uma RCL, a RCL deve ser recriada para atualizar seu manifesto antes que um aplicativo de consumo possa acessar o novo ativo.

Publicação

Quando o aplicativo é publicado, os ativos complementares de todos os projetos e pacotes referenciados são copiados para a pasta wwwroot do aplicativo publicado em _content/{PACKAGE ID}/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID} ao examinar a pasta wwwroot dos ativos publicados.

Recursos adicionais

Modos de exibição do Razor, páginas, controladores, modelos de página, Razor componentes, Componentes de exibição e modelos de dados podem ser inseridos em uma RCL (biblioteca de classes Razor). A RCL pode ser e empacotada e reutilizada. Os aplicativos podem incluir a RCL e substituir as exibições e as páginas que ela contém. Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência.

Exibir ou baixar código de exemplo (como baixar)

Criar uma biblioteca de classes contendo a interface do usuário do Razor

  • No menu Arquivo do Visual Studio, selecione Novo>Projeto.
  • Selecione Aplicativo Web ASP.NET Core.
  • Dê um nome à biblioteca (por exemplo, "RazorClassLib"), >OK. Para evitar uma colisão de nome de arquivo com a biblioteca de exibição gerada, verifique se o nome da biblioteca não termina em .Views.
  • Verifique se o ASP.NET Core 2.1 ou posterior está selecionado.
  • Selecione Biblioteca de Classes Razor>OK.

Uma RCL tem o seguinte arquivo de projeto:

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

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    </PropertyGroup>

    <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
    </ItemGroup>


</Project>

Adicione arquivos Razor na RCL.

Os modelos de ASP.NET Core pressupõem que o conteúdo RCL esteja na pasta Areas. Veja o layout da RCL Pages para criar uma RCL que expõe o conteúdo no ~/Pages em vez de ~/Areas/Pages.

Referenciar conteúdo RCL

A RCL pode ser referenciada por:

Passo a passo: criar um projeto da RCL e usar de um projeto do Razor Pages

Você pode baixar o projeto completo e testá-lo em vez de criá-lo. O download de exemplo contém um código adicional e links que facilitam o teste do projeto. Você pode deixar comentários nesse problema do GitHub com suas opiniões sobre os exemplos de download em relação às instruções passo a passo.

Testar o aplicativo de download

Se você não tiver baixado o aplicativo concluído e preferir criar o projeto do passo a passo, vá para a próxima seção.

Abra o arquivo .sln no Visual Studio. Execute o aplicativo.

Siga as instruções em Testar WebApp1

Criar uma RCL

Nesta seção, uma RCL é criada. Arquivos Razor são adicionados à RCL.

Crie o projeto da RCL:

  • No menu Arquivo do Visual Studio, selecione Novo>Projeto.
  • Selecione Aplicativo Web ASP.NET Core.
  • Nomeie o aplicativo RazorUIClassLib>OK.
  • Verifique se o ASP.NET Core 2.1 ou posterior está selecionado.
  • Selecione Biblioteca de Classes Razor>OK.
  • Adicionar um arquivo de exibição parcial Razor chamado RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml.

Adicionar pastas e arquivos Razor ao projeto

  • Substitua a marcação em RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml pelo seguinte código:

    <h3>_Message.cshtml partial view.</h3>
    
    <p>RazorUIClassLib\Areas\MyFeature\Pages\Shared\_Message.cshtml</p>
    
  • Substitua a marcação em RazorUIClassLib/Areas/MyFeature/Pages/Page1.cshtml pelo seguinte código:

    @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" />
    

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers é necessário para usar a exibição parcial (<partial name="_Message" />). Em vez de incluir a diretiva @addTagHelper, você pode adicionar um arquivo _ViewImports.cshtml. Por exemplo:

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

    Para obter mais informações sobre _ViewImports.cshtml, confira Importando diretivas compartilhadas

  • Crie a biblioteca de classes para verificar se não há nenhum erro de compilador:

    dotnet build RazorUIClassLib
    

A saída de build contém RazorUIClassLib.dll e RazorUIClassLib.Views.dll. RazorUIClassLib.Views.dll contém o conteúdo de Razor compilado.

Use a biblioteca da interface do usuário do Razor de um projeto do Razor Pages

Crie o aplicativo Web do Razor Pages:

  • No Gerenciador de Soluções, clique com o botão direito do mouse na solução >Adicionar>Novo projeto.

  • Selecione Aplicativo Web ASP.NET Core.

  • Nomeie o aplicativo como WebApp1.

  • Verifique se o ASP.NET Core 2.1 ou posterior está selecionado.

  • Selecione Aplicativo Web>OK.

  • No Gerenciador de Soluções, clique com o botão direito do mouse em WebApp1 e selecione Definir como projeto de inicialização.

  • No Gerenciador de Soluções, clique com o botão direito do mouse em WebApp1 e selecione Dependências de Build>Dependências do Projeto.

  • Marque RazorUIClassLib como uma dependência de WebApp1.

  • No Gerenciador de Soluções, clique com o botão direito do mouse em WebApp1 e selecione Adicionar>Referência.

  • Na caixa de diálogo Gerenciador de Referências, marque RazorUIClassLib>OK.

Execute o aplicativo.

Testar o WebApp1

Navegue até /MyFeature/Page1 para verificar se a biblioteca de classes da interface do usuário Razor está em uso.

Substituir exibições, exibições parciais e páginas

Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência. Por exemplo, adicione WebApp1/Areas/MyFeature/Pages/Page1.cshtml ao WebApp1 e Page1 no WebApp1 terá precedência sobre Page1 na RCL.

No download de exemplo, renomeie WebApp1/Areas/MyFeature2 como WebApp1/Areas/MyFeature para testar a precedência.

Copie a exibição parcial de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml para WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Atualize a marcação para indicar o novo local. Crie e execute o aplicativo para verificar se a versão da parcial do aplicativo está sendo usada.

Layout da RCL Pages

Para fazer referência ao conteúdo da RCL como se fosse parte da pasta Pages do aplicativo Web, crie o projeto da RCL com a seguinte estrutura de arquivos:

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Suponha que RazorUIClassLib/Pages/Shared contenha dois arquivos parciais: _Header.cshtml e _Footer.cshtml. As marcas <partial> podem ser adicionadas ao arquivo _Layout.cshtml:

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

Modos de exibição do Razor, páginas, controladores, modelos de página, Razor componentes, Componentes de exibição e modelos de dados podem ser inseridos em uma RCL (biblioteca de classes Razor). A RCL pode ser e empacotada e reutilizada. Os aplicativos podem incluir a RCL e substituir as exibições e as páginas que ela contém. Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência.

Exibir ou baixar código de exemplo (como baixar)

Criar uma biblioteca de classes contendo a interface do usuário do Razor

  • No Visual Studio, selecione Criar um projeto.
  • Selecione Biblioteca de Classes Razor>Avançar.
  • Dê um nome à biblioteca (por exemplo, "RazorClassLib"), >Criar. Para evitar uma colisão de nome de arquivo com a biblioteca de exibição gerada, verifique se o nome da biblioteca não termina em .Views.
  • Selecione Páginas e exibições de suporte se precisar dar suporte a exibições. Por padrão, somente Razor Pages é compatível. Selecione Criar.

O modelo de RCL (biblioteca de classes) Razor usa o desenvolvimento de componentes Razor por padrão. A opção Páginas e exibições de suporte dá suporte a páginas e exibições.

Adicione arquivos Razor na RCL.

Os modelos de ASP.NET Core pressupõem que o conteúdo RCL esteja na pasta Areas. Veja o layout da RCL Pages abaixo para criar uma RCL que expõe o conteúdo no ~/Pages em vez de ~/Areas/Pages.

Referenciar conteúdo RCL

A RCL pode ser referenciada por:

Substituir exibições, exibições parciais e páginas

Quando uma exibição, uma exibição parcial ou uma página Razor for encontrada no aplicativo Web e na RCL, a marcação Razor (arquivo .cshtml) no aplicativo Web terá precedência. Por exemplo, adicione WebApp1/Areas/MyFeature/Pages/Page1.cshtml ao WebApp1 e Page1 no WebApp1 terá precedência sobre Page1 na RCL.

No download de exemplo, renomeie WebApp1/Areas/MyFeature2 como WebApp1/Areas/MyFeature para testar a precedência.

Copie a exibição parcial de RazorUIClassLib/Areas/MyFeature/Pages/Shared/_Message.cshtml para WebApp1/Areas/MyFeature/Pages/Shared/_Message.cshtml. Atualize a marcação para indicar o novo local. Crie e execute o aplicativo para verificar se a versão da parcial do aplicativo está sendo usada.

Se a RCL usar Razor Pages, habilite os serviços e os pontos de extremidade do Razor Pages no aplicativo de hospedagem:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");

        endpoints.MapRazorPages();
    });
}

Layout da RCL Pages

Para fazer referência ao conteúdo da RCL como se fosse parte da pasta Pages do aplicativo Web, crie o projeto da RCL com a seguinte estrutura de arquivos:

  • RazorUIClassLib/Pages
  • RazorUIClassLib/Pages/Shared

Suponha que RazorUIClassLib/Pages/Shared contenha dois arquivos parciais: _Header.cshtml e _Footer.cshtml. As marcas <partial> podem ser adicionadas ao arquivo _Layout.cshtml:

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

Adicione o arquivo _ViewStart.cshtml à pasta do Pages projeto RCL para usar o arquivo _Layout.cshtml do aplicativo Web de host:

@{
    Layout = "_Layout";
}

Criar uma RCL com ativos estáticos

Uma RCL pode exigir ativos estáticos complementares que podem ser referenciados pela RCL ou pelo aplicativo de consumo da RCL. O ASP.NET Core permite a criação de RCLs que incluem ativos estáticos disponíveis para um aplicativo de consumo.

Para incluir ativos complementares como parte de uma RCL, crie uma pasta wwwroot na biblioteca de classes e inclua todos os arquivos necessários nessa pasta.

Ao empacotar uma RCL, todos os ativos complementares na pasta wwwroot são incluídos automaticamente no pacote.

Use o comando dotnet pack em vez da versão nuget pack do NuGet.exe.

Excluir ativos estáticos

Para excluir ativos estáticos, adicione o caminho de exclusão desejado ao grupo de propriedades $(DefaultItemExcludes) no arquivo de projeto. Separe entradas com ponto e vírgula (;).

No exemplo a seguir, a folha de estilos lib.css na pasta wwwroot não é considerada um ativo estático e não está incluída na RCL publicada:

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

Integração com Typescript

Para incluir arquivos TypeScript em uma RCL:

  1. Faça referência ao pacote NuGet Microsoft.TypeScript.MSBuild no projeto.

    Observação

    Para obter diretrizes sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes no Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas de pacote em NuGet.org.

  2. Coloque os arquivos TypeScript (.ts) fora da pasta wwwroot. Por exemplo, coloque os arquivos em uma pasta Client.

  3. Configure a saída de build do TypeScript para a pasta wwwroot. Defina a propriedade TypescriptOutDir dentro de um PropertyGroup no arquivo de projeto:

    <TypescriptOutDir>wwwroot</TypescriptOutDir>
    
  4. Inclua o destino TypeScript como uma dependência do destino ResolveCurrentProjectStaticWebAssets adicionando o seguinte destino dentro de um PropertyGroup no arquivo de projeto:

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

Consumir conteúdo de uma RCL referenciada

Os arquivos incluídos na pasta wwwroot da RCL são expostos à RCL ou ao aplicativo de consumo no prefixo _content/{PACKAGE ID}/. Por exemplo, uma biblioteca com um nome de assembly de Razor.Class.Lib e sem um <PackageId> especificado em seu arquivo de projeto resulta em um caminho para o conteúdo estático em _content/Razor.Class.Lib/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID}.

O aplicativo de consumo faz referência a ativos estáticos fornecidos pela biblioteca com <script>, <style>, <img> e outras marcas HTML. O aplicativo de consumo deve ter suporte a arquivos estáticos habilitado em Startup.Configure:

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

    app.UseStaticFiles();

    ...
}

Ao executar o aplicativo de consumo da saída de build (dotnet run), os ativos da Web estáticos são habilitados por padrão no ambiente de desenvolvimento. Para dar suporte a ativos em outros ambientes ao executar a partir da saída de build, chame UseStaticWebAssets no construtor de host em 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>();
            });
}

A chamada de UseStaticWebAssets não é necessária ao executar um aplicativo da saída publicada (dotnet publish).

Fluxo de desenvolvimento de vários projetos

Quando o aplicativo de consumo é executado:

  • Os ativos na RCL permanecem em suas pastas originais. Os ativos não são movidos para o aplicativo de consumo.
  • Qualquer alteração na pasta wwwroot da RCL é refletida no aplicativo de consumo depois que a RCL é reconstruída e sem recriar o aplicativo de consumo.

Quando a RCL é criada, um manifesto é produzido que descreve os locais de ativos da Web estáticos. O aplicativo de consumo lê o manifesto em runtime para consumir os ativos de projetos e pacotes referenciados. Quando um novo ativo é adicionado a uma RCL, a RCL deve ser recriada para atualizar seu manifesto antes que um aplicativo de consumo possa acessar o novo ativo.

Publicação

Quando o aplicativo é publicado, os ativos complementares de todos os projetos e pacotes referenciados são copiados para a pasta wwwroot do aplicativo publicado em _content/{PACKAGE ID}/. Ao produzir um pacote NuGet e o nome do assembly não é o mesmo que a ID do pacote (<PackageId> no arquivo de projeto da biblioteca), use a ID do pacote conforme especificado no arquivo de projeto para {PACKAGE ID} ao examinar a pasta wwwroot dos ativos publicados.

Recursos adicionais