Integrar componentes Razor do ASP.NET Core em aplicativos do ASP.NET Core
Este artigo explica os cenários de integração de componentes do Razor em aplicativos do ASP.NET Core.
Integração de componentes Razor
Os componentes do Razor podem ser integrados a Razor Pages, MVC e outros tipos de aplicativos ASP.NET Core. Os componentes do Razor também podem ser integrados a qualquer aplicativo Web, incluindo aplicativos não baseados em ASP.NET Core, como elementos HTML personalizados.
Use as diretrizes nas seções a seguir, dependendo dos requisitos do aplicativo:
- Para integrar componentes que não são roteáveis diretamente de solicitações de usuário, siga as diretrizes na seção Usar componentes não roteáveis em páginas ou exibições. Siga estas diretrizes quando o aplicativo tiver que inserir componentes somente em exibições e páginas já existentes com o Auxiliar de Marcação de Componente.
- Para integrar componentes com suporte Blazor completo, siga as diretrizes na seção Adicionar suporte a um aplicativo ASP.NET Core Blazor .
Usar componentes não roteáveis em páginas ou exibições
Use as seguintes diretrizes para integrar Razor componentes em páginas ou exibições de um aplicativo Razor Pages ou MVC existente com o Auxiliar de Marcação do Componente.
Observação
Se o aplicativo exigir componentes roteáveis diretamente (não inseridos em páginas ou exibições), ignore esta seção e use as diretrizes na seção Adicionar Blazor suporte a um aplicativo ASP.NET Core.
Quando a pré-renderização do servidor é usada e a página ou exibição é renderizada:
- O componente é pré-renderizado com a página ou exibição.
- Perda do estado inicial do componente usado para pré-renderização.
- O novo estado componente é criado quando a SignalR conexão é estabelecida.
Para obter mais informações sobre modos de renderização, incluindo a renderização de componente estático não interativo, consulte Auxiliar de Marca de Componente no ASP.NET Core. Para salvar o estado de componentes Razor pré-renderizados, consulte Auxiliar de Marcas do Estado do Componente Persistente no ASP.NET Core.
Adicione uma pasta Components
à pasta raiz do projeto.
Adicione um arquivo de importações à pasta Components
com o seguinte conteúdo. Alterar o {APP NAMESPACE}
espaço reservado para o namespace do projeto.
Components/_Imports.razor
:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components
No arquivo de layout do projeto (Pages/Shared/_Layout.cshtml
em Razor aplicativos Pages ou em aplicativos MVC Views/Shared/_Layout.cshtml
):
Adicione a seguinte marca
<base>
e Auxiliar de Marca de Componente para um componente HeadOutlet à marcação<head>
:<base href="~/" /> <component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" render-mode="ServerPrerendered" />
O
href
valor (o caminho base do aplicativo) no exemplo anterior pressupõe que o aplicativo reside no caminho da URL raiz (/
). Se o aplicativo for um subaplicação, siga as diretrizes na seção Caminho Base do aplicativo do artigo Hospedar e implantar ASP.NET CoreBlazor.O componente HeadOutlet é usado para renderizar o conteúdo de cabeçalho (
<head>
) para títulos de página (componente PageTitle) e outros elementos de cabeçalho (componente HeadContent) definidos por componentes Razor. Para mais informações, confira o Controle de conteúdo de cabeçalhoBlazor em aplicativos do ASP.NET Core.Adicionar uma:
<script>
marca para oblazor.web.js
script de imediato, antes daScripts
seção renderizar (@await RenderSectionAsync(...)
):<script src="_framework/blazor.web.js"></script>
A estrutura Blazor adiciona automaticamente o script
blazor.web.js
ao aplicativo.
Observação
Normalmente, o layout é carregado por meio de um arquivo _ViewStart.cshtml
.
Adicione um componente não operacional (no-op) App
ao projeto.
Components/App.razor
:
@* No-op App component *@
No local em que os serviços são registrados, adicione serviços para componentes Razor e serviços para dar suporte à renderização de componentes do Servidor Interativo.
Na parte superior do arquivo Program
, adicione uma instrução using
à parte superior do arquivo para os componentes do projeto:
using {APP NAMESPACE}.Components;
Na linha anterior, altere o espaço reservado {APP NAMESPACE}
para o namespace do aplicativo. Por exemplo:
using BlazorSample.Components;
No arquivo Program
antes da linha que cria o aplicativo (builder.Build()
):
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
Para obter mais informações sobre como adicionar suporte para componentes de Servidor Interativo e WebAssembly, consulte Modos de renderização do ASP.NET Core Blazor.
No arquivo Program
, imediatamente após a chamada para mapear Razor Pages (MapRazorPages) em um aplicativo Razor Pages ou para mapear a rota do controlador padrão (MapControllerRoute) em um aplicativo MVC, chame MapRazorComponents para descobrir os componentes disponíveis e especifique o componente raiz do aplicativo (o primeiro componente carregado). Por padrão, o componente raiz do aplicativo é o componente App
(App.razor
). Encadear uma chamada para AddInteractiveServerRenderMode para configurar a renderização interativa do lado do servidor (SSR interativa) para o aplicativo:
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
Observação
Se o aplicativo ainda não foi atualizado para incluir o Middleware Antiforgery, adicione a seguinte linha após UseAuthorization ser chamado:
app.UseAntiforgery();
Integrar componentes em qualquer página ou exibição. Por exemplo, adicione um componente EmbeddedCounter
à pasta Components
do projeto.
Components/EmbeddedCounter.razor
:
<h1>Embedded Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Razor Pages :
Na página do Index
projeto de um Razor aplicativo Pages, adicione oEmbeddedCounter
namespace do componente e encorpore o componente na página. Ao carregar a Index
página, o EmbeddedCounter
componente é pré-renderizado. No exemplo a seguir, substitua o espaço reservado {APP NAMESPACE}
pelo namespace do projeto.
Pages/Index.cshtml
:
@page
@using {APP NAMESPACE}.Components
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />
MVC:
Na exibição do Index
projeto de um aplicativo MVC, adicione o EmbeddedCounter
namespace do componente e encorpore o componente na exibição. Ao carregar a exibiçãoIndex
, o EmbeddedCounter
componente é pré-renderizado. No exemplo a seguir, substitua o espaço reservado {APP NAMESPACE}
pelo namespace do projeto.
Views/Home/Index.cshtml
:
@using {APP NAMESPACE}.Components
@{
ViewData["Title"] = "Home Page";
}
<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />
Adicionar o suporte para o Blazor a um aplicativo ASP.NET Core
Esta seção aborda a adição de suporte para o Blazor a um aplicativo ASP.NET Core:
- Adicionar renderização estática do lado do servidor (SSR estático)
- Habilitar a renderização interativa do lado do servidor (SSR interativo)
- Habilitar a renderização automática interativa (automática) ou do lado do cliente (CSR)
Observação
Para os exemplos nesta seção, o nome e o namespace do aplicativo de exemplo são BlazorSample
.
Adicionar renderização estática do lado do servidor (SSR estático)
Adicione uma pasta Components
ao aplicativo.
Adicione o arquivo a seguir _Imports
para namespaces usados por componentes Razor.
Components/_Imports.razor
:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components
Altere o espaço reservado do namespace ({APP NAMESPACE}
) para o namespace do aplicativo. Por exemplo:
@using BlazorSample
@using BlazorSample.Components
Adicione o roteador Blazor (<Router>
, Router) ao aplicativo em um componente Routes
, que é colocado na pasta do aplicativo Components
.
Components/Routes.razor
:
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
Adicione um componente App
ao aplicativo, que serve como o componente raiz, que é o primeiro componente que o aplicativo carrega.
Components/App.razor
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="@Assets["{ASSEMBLY NAME}.styles.css"]" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="{ASSEMBLY NAME}.styles.css" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
O espaço reservado {ASSEMBLY NAME}
é o nome do assembly do aplicativo. Por exemplo, um projeto com um nome de assembly ContosoApp
usa o nome de arquivo de folha de estilo ContosoApp.styles.css
.
Adicione uma pasta Pages
à pasta Components
para manter componentes roteáveis Razor.
Adicione o seguinte componente Welcome
para demonstrar o SSR estático.
Components/Pages/Welcome.razor
:
@page "/welcome"
<PageTitle>Welcome!</PageTitle>
<h1>Welcome to Blazor!</h1>
<p>@message</p>
@code {
private string message =
"Hello from a Razor component and welcome to Blazor!";
}
No arquivo do projeto Program
do ASP.NET Core:
Adicione uma instrução
using
à parte superior do arquivo para os componentes do projeto:using {APP NAMESPACE}.Components;
Na linha anterior, altere o espaço reservado
{APP NAMESPACE}
para o namespace do aplicativo. Por exemplo:using BlazorSample.Components;
Adicione serviços de componente Razor (AddRazorComponents), que também adiciona automaticamente serviços antifalsificação (AddAntiforgery). Adicione a linha a seguir antes da linha que chama
builder.Build()
):builder.Services.AddRazorComponents();
Adicione o middleware antifalsificação ao pipeline de processamento de solicitação com UseAntiforgery. UseAntiforgery é chamado após a chamada para UseRouting. Se houver chamadas para UseRouting e UseEndpoints, a chamada para UseAntiforgery deve ser feita entre elas. Uma chamada para UseAntiforgery deve ser feita após chamadas para UseAuthenticatione UseAuthorization.
app.UseAntiforgery();
Adicione MapRazorComponents ao pipeline de processamento de solicitação do aplicativo com o componente
App
(App.razor
) especificado como o componente raiz padrão (o primeiro componente carregado). Coloque o seguinte código antes da linha que chamaapp.Run
:app.MapRazorComponents<App>();
Quando o aplicativo é executado, o componente Welcome
é acessado no ponto de extremidade /welcome
.
Habilitar a renderização interativa do lado do servidor (SSR interativo)
Siga as diretrizes na seção Adicionar renderização estática do lado do servidor (SSR estático).
No arquivo do aplicativo Program
, adicione uma chamada ao local AddInteractiveServerComponents em que os Razor serviços de componente são adicionados com AddRazorComponents:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
Adicione uma chamada para AddInteractiveServerRenderMode em que os componentes Razor são mapeados com MapRazorComponents:
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
Adicione o seguinte componente Counter
ao aplicativo que adota a renderização interativa do lado do servidor (SSR interativa).
Components/Pages/Counter.razor
:
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Quando o aplicativo é executado, o componente Counter
é acessado em /counter
.
Habilitar a renderização automática interativa (automática) ou do lado do cliente (CSR)
Siga as diretrizes na seção Adicionar renderização estática do lado do servidor (SSR estático).
Os componentes que usam o modo de renderização automática interativa inicialmente usam SSR interativo. O runtime do .NET e o lote de aplicativos são baixados para o cliente em segundo plano e armazenados em cache para que possam ser utilizados em visitas futuras. Os componentes que usam o modo de renderização WebAssembly interativo só são renderizados interativamente no cliente depois que o pacote Blazor é baixado e o runtime Blazor é ativado. Tenha em mente que, ao usar os modos de renderização Interativa automática ou Interativa WebAssembly, o código do componente baixado para o cliente não é privado. Para obter mais informações, consulte ASP.NET Core Blazor modos de renderização.
Depois de decidir qual modo de renderização adotar:
- Se você planeja adotar o modo de renderização automática interativa, siga as diretrizes na seção Habilitar renderização interativa do lado do servidor (SSR interativa).
- Se você planeja adotar apenas a renderização interativa do WebAssembly, continue sem adicionar SSR interativo.
Adicione uma referência de pacote para o Microsoft.AspNetCore.Components.WebAssembly.Server
pacote NuGet ao aplicativo.
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.
Crie um Blazor Web App doador para fornecer ativos ao aplicativo. Siga as diretrizes no artigo Ferramentas do ASP.NET Core Blazor, selecionando o suporte para os seguintes recursos de modelo ao gerar o Blazor Web App.
Para o nome do aplicativo, use o mesmo nome do aplicativo ASP.NET Core, o que resulta na correspondência da marcação de nome do aplicativo em componentes e namespaces correspondentes no código. O uso do mesmo nome/namespace não é estritamente necessário, pois os namespaces podem ser ajustados depois que os ativos são movidos do aplicativo doador para o aplicativo ASP.NET Core. No entanto, o tempo é salvo correspondendo aos namespaces no início.
Visual Studio:
- Para o modo de renderização interativo, selecione Automático (servidor e WebAssembly).
- Defina o local de interatividade como por página/componente.
- Desmarque a caixa de seleção para incluir páginas de exemplo.
.NET CLI:
- Use a opção
-int Auto
. - Não use a opção
-ai|--all-interactive
. - Passe a opção
-e|--empty
.
No Blazor Web App doador, copie todo o projeto .Client
para a pasta de solução do aplicativo ASP.NET Core.
Importante
Não copie a pasta .Client
para a pasta do projeto do ASP.NET Core. A melhor abordagem para organizar soluções .NET é colocar cada projeto da solução em sua própria pasta dentro de uma pasta de solução de nível superior. Se uma pasta de solução acima da pasta do projeto ASP.NET Core não existir, crie uma. Em seguida, copie a pasta do projeto .Client
do Blazor Web App doador para a pasta da solução. A estrutura final da pasta do projeto deve ter o seguinte layout:
BlazorSampleSolution
(pasta de solução de nível superior)BlazorSample
(projeto original do ASP.NET Core)BlazorSample.Client
(pasta do projeto.Client
do Blazor Web App doador)
Para o arquivo de solução ASP.NET Core, você pode deixá-lo na pasta do projeto ASP.NET Core. Como alternativa, você pode mover o arquivo de solução ou criar um novo na pasta de solução de nível superior, desde que as referências do projeto apontem corretamente para os arquivos de projeto (.csproj
) dos dois projetos na pasta da solução.
Se você nomeou o Blazor Web App doador quando criou o projeto do doador da mesma forma que o aplicativo ASP.NET Core, os namespaces usados pelos ativos doados corresponderão aos do aplicativo ASP.NET Core. Você não deve precisar executar mais etapas para corresponder aos namespaces. Se você usou um namespace diferente ao criar o projeto Blazor Web App doador, deverá ajustar os namespaces entre os ativos doados para corresponder se você pretende usar o rest dessas diretrizes exatamente como apresentado. Se os namespaces não corresponderem, ajuste os namespaces antes de prosseguirou ajuste os namespaces conforme você segue as orientações restantes nesta seção.
Exclua o Blazor Web App doador, pois ele não tem mais uso nesse processo.
Adicione o projeto .Client
à solução:
Visual Studio: clique com o botão direito do mouse na solução no Gerenciador de Soluções e selecione Adicionar>Projeto Existente. Navegue até a
.Client
pasta e selecione o arquivo de projeto (.csproj
).CLI do .NET: use o
dotnet sln add
comando para adicionar o projeto.Client
à solução.
Adicione uma referência de projeto do projeto ASP.NET Core ao projeto cliente:
Visual Studio: clique com o botão direito do mouse no projeto ASP.NET Core e selecione Adicionar>Referência do Projeto. Selecione o projeto
.Client
e selecione OK.CLI do .NET: na pasta do projeto do ASP.NET Core, use o seguinte comando:
dotnet add reference ../BlazorSample.Client/BlazorSample.Client.csproj
O comando anterior pressupõe o seguinte:
- O nome do arquivo do projeto é
BlazorSample.Client.csproj
. - O projeto
.Client
está em uma pastaBlazorSample.Client
dentro da pasta da solução. A pasta.Client
está lado a lado com a pasta do projeto ASP.NET Core.
Para obter mais informações sobre o comando
dotnet add reference
, consultedotnet add reference
(documentação do .NET).- O nome do arquivo do projeto é
Faça as seguintes alterações no arquivo do Program
aplicativo ASP.NET Core:
Adicione serviços de componentes do WebAssembly Interativo com AddInteractiveWebAssemblyComponents em que os serviços de componente Razor são adicionados com AddRazorComponents.
Para renderização automática interativa:
builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents();
Somente para renderização do WebAssembly Interativo:
builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();
Adicione o modo de renderização WebAssembly Interativo (AddInteractiveWebAssemblyRenderMode) e assemblies adicionais ao projeto
.Client
, em que os componentes Razor são mapeados com MapRazorComponents.Para renderização automática interativa (automática):
app.MapRazorComponents<App>() .AddInteractiveServerRenderMode() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
Somente para renderização do WebAssembly Interativo:
app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
Nos exemplos anteriores, altere
BlazorSample.Client
para corresponder ao namespace do projeto.Client
.
Adicione uma pasta Pages
ao projeto .Client
.
Se o projeto ASP.NET Core tiver um componente existente Counter
:
- Mova o componente para a pasta
Pages
do projeto.Client
. - Remova a diretiva
@rendermode
na parte superior do arquivo de componente.
Se o aplicativo ASP.NET Core não tiver um componente Counter
, adicione o seguinte componente Counter
(Pages/Counter.razor
) ao projeto .Client
:
@page "/counter"
@rendermode InteractiveAuto
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Se o aplicativo estiver adotando apenas a renderização do WebAssembly Interativo, remova a diretiva e o valor @rendermode
:
- @rendermode InteractiveAuto
Execute a solução no projeto de aplicativo do ASP.NET Core:
Visual Studio: confirme se o projeto ASP.NET Core está selecionado no Gerenciador de Soluções ao executar o aplicativo.
CLI do .NET: execute o projeto na pasta do projeto ASP.NET Core.
Para carregar o componente Counter
, navegue até /counter
.
Implementar layout e estilos Blazor
Opcionalmente, atribua um componente de layout padrão usando o parâmetro RouteView.DefaultLayout do componente RouteView
.
Em Routes.razor
, o exemplo a seguir usa um componente MainLayout
como layout padrão:
<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
Para obter mais informações, confira os layouts ASP.NET Core Blazor.
Blazor O layout do modelo de projeto e as folhas de estilo estão disponíveis no dotnet/aspnetcore
repositório do GitHub:
MainLayout.razor
MainLayout.razor.css
NavMenu.razor
NavMenu.razor.css
Observação
Os links de documentação para a fonte de referência do .NET geralmente carregam o branch padrão do repositório, que representa o desenvolvimento atual da próxima versão do .NET. Para selecionar uma marca para uma versão específica, use a lista suspensa para Alternar branches ou marcas. Para saber mais, confira Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Dependendo de como você organiza seus arquivos de layout no aplicativo, pode ser necessário adicionar uma instrução @using
para a pasta dos arquivos de layout no arquivo _Imports.razor
do aplicativo para exibi-los para uso nos componentes do aplicativo.
Não há necessidade de fazer referência explícita a folhas de estilo ao usar o isolamento CSS. A estrutura Blazor agrupa automaticamente folhas de estilo de componentes individuais. A folha de estilo agrupada do aplicativo já é referenciada no componente App
do aplicativo ({ASSEMBLY NAME}.styles.css
, em que o espaço reservado {ASSEMBLY NAME}
é o nome do assembly do aplicativo).
Retornar um RazorComponentResult
de uma ação do controlador MVC
Uma ação do controlador MVC pode retornar um componente com RazorComponentResult<TComponent>.
Components/Welcome.razor
:
<PageTitle>Welcome!</PageTitle>
<h1>Welcome!</h1>
<p>@Message</p>
@code {
[Parameter]
public string? Message { get; set; }
}
Em um controlador:
public IResult GetWelcomeComponent() =>
new RazorComponentResult<Welcome>(new { Message = "Hello, world!" });
Somente a marcação HTML para o componente renderizado é retornada. Os layouts e a marcação de página HTML não são renderizados automaticamente com o componente. Para produzir uma página HTML completa, o aplicativo pode manter um layout Blazor que fornece marcação HTML para <html>
, <head>
, <body>
e outras marcas. O componente inclui o layout com a diretiva @layout
Razor no início do arquivo de definição de componente, Welcome.razor
, por exemplo nesta seção. O seguinte exemplo pressupõe que o aplicativo tenha um layout chamado RazorComponentResultLayout
(Components/Layout/RazorComponentResultLayout.razor
):
@using BlazorSample.Components.Layout
@layout RazorComponentResultLayout
Você pode evitar colocar a instrução @using
da pasta Layout
em componentes individuais movendo-a para o arquivo _Imports.razor
do aplicativo.
Para obter mais informações, confira os layouts ASP.NET Core Blazor.
Namespaces de componente
Ao usar uma pasta personalizada para manter os componentes Razor do projeto, adicione o namespace que representa a pasta à página/exibição ou ao _ViewImports.cshtml
arquivo. No exemplo a seguir:
- Os componentes são armazenados na pasta
Components
do projeto. - O espaço reservado
{APP NAMESPACE}
é o namespace do projeto.Components
representa o nome da pasta.
@using {APP NAMESPACE}.Components
Por exemplo:
@using BlazorSample.Components
O _ViewImports.cshtml
arquivo está localizado na Pages
pasta de um Razor aplicativo Pages ou na Views
pasta de um aplicativo MVC.
Para mais informações, confira osComponentes Razor do ASP.NET Core.