Consumir componentes ASP.NET Core Razor de uma biblioteca de classes Razor (RCL)
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Advertência
Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Os componentes podem ser compartilhados em uma biblioteca de classes Razor (RCL) entre projetos. Inclua componentes e ativos estáticos em um aplicativo de:
Assim como os componentes são tipos .NET regulares, os componentes fornecidos por um RCL são assemblies .NET normais.
Criar uma RCL
- Crie um novo projeto.
- Na caixa de diálogo Criar um novo projeto, selecione Biblioteca de ClassesRazor na lista de modelos de projeto ASP.NET Core. Selecione Avançar.
- Na caixa de diálogo Configurar o seu novo projeto, forneça um nome de projeto no campo Nome do projeto. Exemplos neste tópico utilizam o nome do projeto
ComponentLibrary
. Selecione Avançar. - Na caixa de diálogo Informações Adicionais, não selecione Páginas e Vistas de Suporte. Selecione Criar.
- Adicione o RCL a uma solução:
- Abra a solução.
- Clique com o botão direito do rato na solução no Solution Explorer. Selecione Adicionar>projeto existente.
- Navegue até ao ficheiro de projeto da RCL.
- Selecione o ficheiro de projeto da RCL (
.csproj
).
- Adicione uma referência ao RCL a partir da aplicação:
- Clique com o botão direito do mouse no projeto do aplicativo. Selecione Adicionar referência de projeto>.
- Selecione o projeto RCL. Selecione OK.
Consumir um componente Razor de uma RCL
Para consumir componentes de um RCL em outro projeto, use uma das seguintes abordagens:
- Use o nome completo do tipo de componente, que inclui o namespace da RCL.
- Componentes individuais podem ser adicionados pelo nome próprio sem o namespace da RCL se a diretiva
@using
de Razordeclarar o namespace da RCL. Use as seguintes abordagens:- Adicione a diretiva
@using
a componentes individuais. - Inclua a diretiva
@using
no arquivo_Imports.razor
de nível superior para disponibilizar os componentes da biblioteca para um projeto inteiro. Adicione a diretiva a um arquivo_Imports.razor
em qualquer nível para aplicar o namespace a um único componente ou conjunto de componentes dentro de uma pasta. Quando um arquivo_Imports.razor
é usado, componentes individuais não exigem uma diretiva@using
para o namespace da RCL.
- Adicione a diretiva
Nos exemplos a seguir, ComponentLibrary
é um RCL que contém o componente Component1
. O componente Component1
é um componente de exemplo adicionado automaticamente a uma RCL criada a partir do modelo de projeto RCL que não é criada para suportar páginas e visualizações.
Component1.razor
no ComponentLibrary
RCL:
<div class="my-component">
This component is defined in the <strong>ComponentLibrary</strong> package.
</div>
No aplicativo que consome o RCL, faça referência ao componente Component1
usando seu namespace, como mostra o exemplo a seguir.
ConsumeComponent1.razor
:
@page "/consume-component-1"
<h1>Consume component (full namespace example)</h1>
<ComponentLibrary.Component1 />
Como alternativa, adicione uma diretiva @using
e use o componente sem seu namespace. A seguinte diretiva @using
também pode aparecer em qualquer arquivo _Imports.razor
na pasta atual ou acima dela.
ConsumeComponent2.razor
:
@page "/consume-component-2"
@using ComponentLibrary
<h1>Consume component (<code>@@using</code> example)</h1>
<Component1 />
Para componentes de biblioteca que usam de isolamento CSS, os estilos de componente são disponibilizados automaticamente para o aplicativo consumidor. Não há necessidade de vincular ou importar manualmente as folhas de estilo de componentes individuais da biblioteca ou seu arquivo CSS agregado no aplicativo que consome a biblioteca. O aplicativo usa importações CSS para fazer referência aos estilos agrupados da RCL. Os estilos incorporados não são publicados como um recurso Web estático da aplicação que consome a biblioteca. Para uma biblioteca de classes chamada ClassLib
e uma aplicação Blazor com uma folha de estilo BlazorSample.styles.css
, a folha de estilo da RCL é importada automaticamente na parte superior da folha de estilo da aplicação no momento da compilação:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Para os exemplos anteriores, a folha de estilo do Component1
(Component1.razor.css
) é agrupada automaticamente.
Component1.razor.css
no ComponentLibrary
RCL:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
A imagem de fundo também está incluída no modelo de projeto RCL e reside na pasta wwwroot
da RCL.
wwwroot/background.png
no ComponentLibrary
RCL:
Para fornecer estilos adicionais de componentes da biblioteca a partir de folhas de estilo na pasta wwwroot
da biblioteca, adicione as etiquetas da folha de estilo <link>
ao componente consumidor da RCL, como demonstra o próximo exemplo.
Importante
Geralmente, os componentes da biblioteca usam de isolamento CSS para agrupar e fornecer estilos de componentes. Os estilos de componentes que dependem do isolamento CSS são automaticamente disponibilizados para a aplicação que utiliza a RCL. Não há necessidade de vincular ou importar manualmente as folhas de estilo de componentes individuais da biblioteca ou seu arquivo CSS agregado no aplicativo que consome a biblioteca. O exemplo a seguir é para fornecer folhas de estilo globais fora do isolamento CSS, que geralmente não é um requisito para aplicativos típicos que consomem RCLs.
A imagem de fundo a seguir é usada no próximo exemplo. Se você implementar o exemplo mostrado nesta seção, clique com o botão direito do mouse na imagem para salvá-la localmente.
wwwroot/extra-background.png
no ComponentLibrary
RCL:
Adicione uma nova folha de estilo à RCL com uma classe extra-style
.
wwwroot/additionalStyles.css
no ComponentLibrary
RCL:
.extra-style {
border: 2px dashed blue;
padding: 1em;
margin: 1em 0;
background-image: url('extra-background.png');
}
Adicione um componente à RCL que usa a classe extra-style
.
ExtraStyles.razor
no ComponentLibrary
RCL:
<div class="extra-style">
<p>
This component is defined in the <strong>ComponentLibrary</strong> package.
</p>
</div>
Adicione uma página à aplicação que utilize o componente ExtraStyles
da RCL.
ConsumeComponent3.razor
:
@page "/consume-component-3"
@using ComponentLibrary
<h1>Consume component (<code>additionalStyles.css</code> example)</h1>
<ExtraStyles />
Link para a folha de estilo da biblioteca no marcador <head>
do aplicativo (localização do conteúdo <head>
):
Blazor Web Apps:
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
Aplicações Blazor WebAssembly autónomas:
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
Para componentes de biblioteca que usam isolamento CSS , os estilos dos componentes são disponibilizados automaticamente para a aplicação que os utiliza. Não há necessidade de vincular ou importar manualmente as folhas de estilo de componentes individuais da biblioteca ou seu arquivo CSS agregado no aplicativo que consome a biblioteca. O aplicativo usa importações CSS para fazer referência aos estilos agrupados da RCL. Os estilos agrupados não são publicados como um recurso web estático da aplicação que consome a biblioteca. Para uma biblioteca de classes chamada ClassLib
e uma aplicação Blazor com uma folha de estilo BlazorSample.styles.css
, a folha de estilo da RCL é importada automaticamente na parte superior da folha de estilo da aplicação no momento da compilação:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
Para os exemplos anteriores, a folha de estilo do Component1
(Component1.razor.css
) é agrupada automaticamente.
Component1.razor.css
no ComponentLibrary
RCL:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
A imagem de fundo também está incluída no modelo de projeto RCL e reside na pasta wwwroot
da RCL.
wwwroot/background.png
no ComponentLibrary
RCL:
A imagem de fundo e a folha de estilo a seguir são usadas pelo componente de exemplo Component1
da RCL. Não há necessidade de adicionar estes ativos estáticos a uma nova RCL criada a partir do modelo de projeto RCL, uma vez que são adicionados automaticamente pelo modelo de projeto.
wwwroot/background.png
no ComponentLibrary
RCL:
wwwroot/styles.css
no ComponentLibrary
RCL:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
Para fornecer Component1
classe CSS do my-component
, vincule-se à folha de estilo da biblioteca na marcação <head>
do aplicativo (local do conteúdo <head>
):
<link href="_content/ComponentLibrary/styles.css" rel="stylesheet" />
Disponibilizar componentes roteáveis a partir da RCL
Para disponibilizar componentes roteáveis na RCL para solicitações diretas, a montagem da RCL deve ser divulgada ao roteador do aplicativo.
Abra o componente App
do aplicativo (App.razor
). Atribua uma coleção Assembly ao parâmetro AdditionalAssemblies do componente Router para incluir o conjunto da RCL. No exemplo a seguir, o componente ComponentLibrary.Component1
é usado para descobrir a montagem da RCL.
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
Para obter mais informações, consulte ASP.NET Core Blazor roteamento e navegação.
Criar uma RCL com ativos estáticos na pasta wwwroot
Os ativos estáticos de uma RCL estão disponíveis para qualquer aplicação que consuma a biblioteca.
Coloque os ativos estáticos na pasta wwwroot
do RCL e faça referência aos ativos estáticos com o seguinte caminho no aplicativo: _content/{PACKAGE ID}/{PATH AND FILE NAME}
. O espaço reservado {PACKAGE ID}
é a ID de pacote da biblioteca. O ID do pacote assume como padrão o nome do assembly do projeto se <PackageId>
não for especificado no arquivo do projeto. O espaço reservado {PATH AND FILE NAME}
é o caminho e o nome do ficheiro em wwwroot
. Esse formato de caminho também é usado no aplicativo para ativos estáticos fornecidos por pacotes NuGet adicionados à RCL.
O exemplo a seguir demonstra o uso de ativos estáticos RCL com um RCL chamado ComponentLibrary
e um aplicativo Blazor que consome o RCL. O aplicativo tem uma referência de projeto para o ComponentLibrary
RCL.
A seguinte imagem do Jeep® é usada no exemplo desta seção. Se você implementar o exemplo mostrado nesta seção, clique com o botão direito do mouse na imagem para salvá-la localmente.
wwwroot/jeep-yj.png
no ComponentLibrary
RCL:
Adicione o seguinte componente JeepYJ
à RCL.
JeepYJ.razor
no ComponentLibrary
RCL:
<h3>ComponentLibrary.JeepYJ</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
Adicione o seguinte componente Jeep
à aplicação que consome o ComponentLibrary
RCL. O componente Jeep
usa:
- A imagem do Jeep YJ® da pasta
ComponentLibrary
wwwroot
RCL. - O componente
JeepYJ
da RCL.
Jeep.razor
:
@page "/jeep"
@using ComponentLibrary
<div style="float:left;margin-right:10px">
<h3>Direct use</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
</div>
<JeepYJ />
<p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
</p>
Componente Jeep
renderizado:
Para obter mais informações, consulte UI reutilizável Razor em bibliotecas de classe com ASP.NET Core.
Criar um RCL com ficheiros JavaScript colocados junto aos componentes
A colocação de arquivos JavaScript (JS) para componentes Razor é uma maneira conveniente de organizar scripts numa aplicação.
Razor componentes de aplicativos Blazor dispõem os arquivos JS usando a extensão .razor.js
e são publicamente acessíveis usando o caminho para o arquivo no projeto:
{PATH}/{COMPONENT}.razor.js
- O espaço reservado
{PATH}
é o caminho para o componente. - O
{COMPONENT}
é o espaço reservado para o componente.
Quando o aplicativo é publicado, a estrutura move automaticamente o script para a raiz da Web. Os scripts são movidos para bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
, onde os marcadores de posição são:
-
{TARGET FRAMEWORK MONIKER}
é o Target Framework Moniker (TFM). -
{PATH}
é o caminho para o componente. -
{COMPONENT}
é o nome do componente.
Nenhuma alteração é necessária na URL relativa do script, pois Blazor se encarrega de colocar o arquivo JS em ativos estáticos publicados para você.
Esta seção e os exemplos a seguir concentram-se principalmente em explicar a colocação de ficheiros JS. O primeiro exemplo demonstra um arquivo JS colocado com uma função JS comum. O segundo exemplo demonstra o uso de um módulo para carregar uma função, que é a abordagem recomendada para a maioria dos aplicativos de produção. Chamar JS a partir do .NET é totalmente coberto em Chamar funções JavaScript a partir de métodos .NET no ASP.NET Core Blazor, onde se encontram mais explicações sobre a API BlazorJS com exemplos adicionais. A discussão sobre o descarte de componentes, presente no segundo exemplo, é coberta em ciclo de vida de componentes Razor no ASP.NET Core.
O componente JsCollocation1
a seguir carrega um script por meio de um componente HeadContent
e chama uma função JS com IJSRuntime.InvokeAsync. O espaço reservado {PATH}
é o caminho para o componente.
Importante
Se você usar o código a seguir para uma demonstração em um aplicativo de teste, altere o espaço reservado {PATH}
para o caminho do componente (exemplo: Components/Pages
no .NET 8 ou posterior ou Pages
no .NET 7 ou anterior). Em um Blazor Web App (.NET 8 ou posterior), o componente requer um modo de renderização interativo aplicado globalmente ao aplicativo ou à definição do componente.
Adicione o seguinte script após o script Blazor (local do Blazor script de início):
<script src="{PATH}/JsCollocation1.razor.js"></script>
JsCollocation1
componente ({PATH}/JsCollocation1.razor
):
@page "/js-collocation-1"
@inject IJSRuntime JS
<PageTitle>JS Collocation 1</PageTitle>
<h1>JS Collocation Example 1</h1>
<button @onclick="ShowPrompt">Call showPrompt1</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private string? result;
public async Task ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
O ficheiro JS é colocado ao lado do ficheiro de componente JsCollocation1
com o nome de JsCollocation1.razor.js
. No componente JsCollocation1
, o script é referenciado no caminho do arquivo colocado. No exemplo a seguir, a função showPrompt1
aceita o nome do usuário de um Window prompt()
e o retorna ao componente JsCollocation1
para exibição.
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
A abordagem anterior não é recomendada para uso geral em aplicativos de produção porque polui o cliente com funções globais. Uma abordagem melhor para aplicativos de produção é usar módulos JS. Os mesmos princípios gerais se aplicam ao carregamento de um módulo JS a partir de um arquivo JS colocado, como demonstra o próximo exemplo.
O método OnAfterRenderAsync
do componente JsCollocation2
a seguir carrega um módulo JS em module
, que é uma IJSObjectReference da classe componente.
module
é usado para chamar a função showPrompt2
. O placeholder {PATH}
é o caminho para o componente.
Importante
Se utilizares o código a seguir para uma demonstração em uma aplicação de teste, substitui o espaço reservado {PATH}
pelo caminho do componente. Em um Blazor Web App (.NET 8 ou posterior), o componente requer um modo de renderização interativo aplicado globalmente ao aplicativo ou à definição do componente.
JsCollocation2
componente ({PATH}/JsCollocation2.razor
):
@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>JS Collocation 2</PageTitle>
<h1>JS Collocation Example 2</h1>
<button @onclick="ShowPrompt">Call showPrompt2</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private IJSObjectReference? module;
private string? result;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
/*
Change the {PATH} placeholder in the next line to the path of
the collocated JS file in the app. Examples:
./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
*/
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./{PATH}/JsCollocation2.razor.js");
}
}
public async void ShowPrompt()
{
if (module is not null)
{
result = await module.InvokeAsync<string>(
"showPrompt2", "What's your name?");
StateHasChanged();
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
No exemplo anterior, JSDisconnectedException fica preso durante a eliminação do módulo, caso o circuito de SignalR de Blazorseja perdido. Se o código anterior for usado em um aplicativo Blazor WebAssembly, não há conexão SignalR a perder, então você pode remover o bloco de try
-catch
e deixar a linha que descarta o módulo (await module.DisposeAsync();
). Para obter mais informações, consulte ASP.NET Interoperabilidade do Core Blazor JavaScript (JS interoperabilidade).
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
Importante
Não coloque uma tag <script>
para JsCollocation2.razor.js
depois do script Blazor porque o módulo é carregado e armazenado em cache automaticamente quando o dinâmico import()
é invocado.
A utilização de scripts e módulos para JS colocados numa biblioteca de classes Razor (RCL) é suportada apenas para o mecanismo de interoperabilidade JS do Blazor, baseado na interface IJSRuntime. Se estiveres a implementar JavaScript [JSImport]
/[JSExport]
interop, consulta JavaScript JSImport/JSExport interop com ASP.NET Core Blazor.
Para scripts ou módulos fornecidos por uma biblioteca de classes Razor (RCL) usando interoperabilidade baseada em IJSRuntimecom JS, o seguinte caminho é utilizado:
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- O segmento de caminho para o diretório atual (
./
) é necessário para criar o caminho de ativo estático correto para o arquivo JS. - O espaço reservado
{PACKAGE ID}
é o identificador de pacote da RCL (ou o nome da biblioteca de uma biblioteca de classes referenciada pelo aplicativo). - O marcador de posição
{PATH}
é o caminho para o componente. Se um componente Razor estiver localizado na raiz da RCL, o segmento de caminho não será incluído. - O marcador
{COMPONENT}
é o nome do componente. - O marcador de posição
{EXTENSION}
coincide com a extensão do componente,razor
oucshtml
.
No seguinte exemplo de aplicativo Blazor:
- O identificador de pacote da RCL é
AppJS
. - Os scripts de um módulo são carregados para o componente
JsCollocation3
(JsCollocation3.razor
). - O componente
JsCollocation3
está na pastaComponents/Pages
da RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
Forneça componentes e ativos estáticos para vários aplicativos de Blazor hospedados
Para obter mais informações, consulte Vários aplicativos ASP.NET Core hospedados Blazor WebAssembly.
Analisador de compatibilidade do navegador do lado do cliente
Os aplicativos do lado do cliente destinam-se à área de superfície completa da API .NET, mas nem todas as APIs .NET são suportadas no WebAssembly devido a restrições da área restrita do navegador. APIs não suportadas lançam PlatformNotSupportedException quando executadas no WebAssembly. Um analisador de compatibilidade de plataforma avisa o desenvolvedor quando o aplicativo usa APIs que não são suportadas pelas plataformas de destino do aplicativo. Para aplicativos do lado do cliente, isso significa verificar se as APIs são suportadas em navegadores. A anotação de APIs do .NET Framework para o analisador de compatibilidade é um processo contínuo, portanto, nem todas as APIs do .NET Framework estão anotadas no momento.
Blazor Web Appque habilitam componentes Interactive WebAssembly, aplicativos Blazor WebAssembly e projetos RCL habilitam automaticamente verificações de compatibilidade do navegador adicionando browser
como uma plataforma suportada com o item MSBuild SupportedPlatform
. Os desenvolvedores de bibliotecas podem adicionar manualmente o item SupportedPlatform
ao arquivo de projeto de uma biblioteca para habilitar o recurso:
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
Ao criar uma biblioteca, indique que uma API específica não é suportada em navegadores especificando browser
para UnsupportedOSPlatformAttribute:
using System.Runtime.Versioning;
...
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
...
}
Para obter mais informações, consulte Anotando APIs como não suportadas em plataformas específicas (dotnet/designs
repositório GitHub.
Isolamento de JavaScript em módulos JavaScript
Blazor permite o isolamento de JavaScript em módulos JavaScript padrão . O isolamento JavaScript oferece os seguintes benefícios:
- O JavaScript importado não polui mais o namespace global.
- Os consumidores da biblioteca e dos componentes não precisam importar manualmente o JavaScript relacionado.
Para mais informações, consulte Chamar Funções JavaScript de Métodos .NET no ASP.NET Core Blazor.
Evite cortar métodos .NET invocáveis em JavaScript
A revinculação em tempo de execução elimina os métodos .NET invocáveis por JavaScript das instâncias de classe, a menos que sejam explicitamente preservados. Para obter mais informações, consulte Chamar métodos .NET a partir de funções JavaScript no ASP.NET Core Blazor.
Crie, empacote e envie para o NuGet
Como Razor bibliotecas de classe que contêm componentes Razor são bibliotecas .NET padrão, empacotá-las e enviá-las para o NuGet não é diferente de empacotar e enviar qualquer biblioteca para o NuGet. O empacotamento é realizado usando o comando dotnet pack
em um shell de comando:
dotnet pack
Carregue o pacote para o NuGet usando o comando dotnet nuget push
em um shell de comando.
Marcas comerciais
Jeep e Jeep YJ são marcas registadas da FCA US LLC (Stellantis NV).