Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Observação
As soluções hospedadas Blazor WebAssembly permanecem com suporte, mas o modelo de projeto foi removido e não é mais suportado no .NET 8 ou posterior. Este artigo aparece no sumário até ao .NET 7 para referência, mas observe que o .NET 7 é uma versão de Termo de Suporte Padrão, que já não é suportada.
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.
Este artigo explica Razor os cenários de integração de componentes para aplicações hospedadas Blazor WebAssembly, incluindo a pré-renderização dos componentes Razor no servidor.
Importante
As alterações de estrutura nas versões ASP.NET Core levaram a diferentes conjuntos de instruções neste artigo. Antes de usar as diretrizes deste artigo, confirme se o seletor de versão do documento na parte superior deste artigo corresponde à versão do ASP.NET Core que você pretende usar para seu aplicativo.
A pré-renderização pode melhorar a Otimização para Motores de Busca (SEO) ao renderizar conteúdo para a resposta HTTP inicial que os motores de busca podem usar para calcular o ranking da página.
Configuração da solução
Configuração de pré-renderização
Para configurar a pré-renderização para uma aplicação hospedada Blazor WebAssembly :
Hospede o Blazor WebAssembly aplicativo em um aplicativo ASP.NET Core. Uma aplicação autónoma Blazor WebAssembly pode ser adicionada a uma solução ASP.NET Core ou pode usar uma aplicação hospedada Blazor WebAssembly criada a partir do Blazor WebAssembly modelo de projeto com a opção hospedada:
- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
BlazorHosted. - Shell de comandos da CLI do Visual Studio Code/.NET:
dotnet new blazorwasm -ho(use a opção-ho|--hosted). Use a-o|--output {LOCATION}opção para criar uma pasta para a solução e definir os namespaces de projeto da solução. Nos exemplos deste artigo, a solução é denominadaBlazorHosted(dotnet new blazorwasm -ho -o BlazorHosted).
Para os exemplos neste artigo, o nome da solução hospedada (nome do assembly) é
BlazorHosted. O namespace do projeto cliente éBlazorHosted.Client, e o namespace do projeto do servidor éBlazorHosted.Server.- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
Exclua o
wwwroot/index.htmlBlazor WebAssemblyClient arquivo do projeto.Client No projeto, exclua as seguintes linhas em
Program.cs:- builder.RootComponents.Add<App>("#app"); - builder.RootComponents.Add<HeadOutlet>("head::after");Adicione o ficheiro
_Host.cshtmlà pasta do projeto ServerPages. Você pode obter os arquivos de um projeto criado a partir do modelo Blazor Server usando o Visual Studio ou usando o CLI do .NET com odotnet new blazorserver -o BlazorServercomando em um shell de comando (a opção-o BlazorServercria uma pasta para o projeto). Depois de colocar os arquivos na Server pasta doPagesprojeto, faça as seguintes alterações nos arquivos.Faça as seguintes alterações no
_Host.cshtmlarquivo:Atualize o
Pagesnamespace na parte superior do arquivo para corresponder ao namespace das Server páginas do aplicativo. O{APP NAMESPACE}marcador de posição no exemplo seguinte representa o namespace das páginas da aplicação doadora que forneceu o ficheiro_Host.cshtml.Suprimir.
- @namespace {APP NAMESPACE}.PagesAdicione:
@namespace BlazorHosted.Server.PagesAdicione uma diretiva
@usingpara o projeto Client na parte superior do arquivo:@using BlazorHosted.ClientAtualize os links de folha de estilo para apontar para as folhas de estilo do projeto WebAssembly. No exemplo a seguir, o namespace do projeto cliente é
BlazorHosted.Client. O espaço reservado{APP NAMESPACE}representa o namespace da aplicação doadora que forneceu o ficheiro_Host.cshtml. Atualize o Auxiliar de Tag do Componente (<component>) do componenteHeadOutletpara pré-renderizar.Suprimir.
- <link href="css/site.css" rel="stylesheet" /> - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" /> - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />Adicione:
<link href="css/app.css" rel="stylesheet" /> <link href="BlazorHosted.Client.styles.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />Observação
Deixe o
<link>elemento que solicita a folha de estilo do Bootstrap (css/bootstrap/bootstrap.min.css) no lugar.Atualize a origem do Blazor script para usar o script do lado Blazor WebAssembly do cliente:
Suprimir.
- <script src="_framework/blazor.server.js"></script>Adicione:
<script src="_framework/blazor.webassembly.js"></script>Atualize o
render-modedo Auxiliar de Tag de Componente para pré-renderizar o componente raizAppcom WebAssemblyPrerendered:Suprimir.
- <component type="typeof(App)" render-mode="ServerPrerendered" />Adicione:
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />Importante
A pré-renderização não é suportada para endpoints de autenticação (segmento de caminho
/authentication/). Para obter mais informações, consulte ASP.NET Core Blazor WebAssembly cenários de segurança adicionais.
Program.csNo ficheiro do projeto Server, altere o endpoint de fallback do ficheiroindex.htmlpara a página_Host.cshtml.Suprimir.
- app.MapFallbackToFile("index.html");Adicione:
app.MapFallbackToPage("/_Host");Se os projetos Client e Server usarem um ou mais serviços comuns durante a pré-renderização, fatore os registros de serviço em um método que pode ser chamado de ambos os projetos. Para obter mais informações, consulte injeção de dependência do ASP.NET CoreBlazor.
Execute o projeto Server. O aplicativo Blazor WebAssembly hospedado é pré-renderizado pelo projeto Server para clientes.
Configuração para incorporar Razor componentes em páginas ou vistas
As secções e exemplos a seguir para integrar Razor componentes da aplicação ClientBlazor WebAssembly em páginas ou vistas da aplicação servidor exigem configuração adicional.
O Server projeto deve ter os seguintes arquivos e pastas.
Razor Páginas:
Pages/Shared/_Layout.cshtmlPages/Shared/_Layout.cshtml.cssPages/_ViewImports.cshtmlPages/_ViewStart.cshtml
MVC:
Views/Shared/_Layout.cshtmlViews/Shared/_Layout.cshtml.cssViews/_ViewImports.cshtmlViews/_ViewStart.cshtml
Os arquivos anteriores podem ser obtidos gerando um aplicativo a partir dos modelos de projeto ASP.NET Core usando:
- Novas ferramentas de criação de projetos do Visual Studio.
- Abrir um shell de comando e executar
dotnet new webapp -o {PROJECT NAME}(Razor Pages) oudotnet new mvc -o {PROJECT NAME}(MVC). A opção-o|--outputcom um valor para o espaço reservado{PROJECT NAME}fornece um nome para o aplicativo e cria uma pasta para o aplicativo.
Atualize os namespaces no arquivo importado _ViewImports.cshtml para corresponder àqueles em uso pelo Server projeto que recebe os arquivos.
Pages/_ViewImports.cshtml (Razor Páginas):
@using BlazorHosted.Server
@namespace BlazorHosted.Server.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Views/_ViewImports.cshtml (MVC):
@using BlazorHosted.Server
@using BlazorHosted.Server.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Atualize o arquivo de layout importado, que é Pages/Shared/_Layout.cshtml para Razor Pages ou Views/Shared/_Layout.cshtml MVC.
Primeiro, exclua o título e a folha de estilo do projeto doador, que está RPDonor.styles.css no exemplo a seguir. O {PROJECT NAME} espaço reservado representa o nome do aplicativo do projeto doador.
- <title>@ViewData["Title"] - {PROJECT NAME}</title>
- <link rel="stylesheet" href="~/RPDonor.styles.css" asp-append-version="true" />
Inclua os Client estilos do projeto no arquivo de layout. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client. O <title> elemento pode ser atualizado ao mesmo tempo.
Coloque as seguintes linhas no conteúdo do ficheiro de layout:
<title>@ViewData["Title"] - BlazorHosted</title>
<link href="css/app.css" rel="stylesheet" />
<link rel="stylesheet" href="BlazorHosted.Client.styles.css" asp-append-version="true" />
<component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
O layout importado contém dois Home (Index página) e Privacy links de navegação. Para fazer com que os Home links apontem para o aplicativo hospedado Blazor WebAssembly , altere os hiperlinks:
- <a class="navbar-brand" asp-area="" asp-page="/Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Em um arquivo de layout MVC:
- <a class="navbar-brand" asp-area="" asp-controller="Home"
- asp-action="Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-controller="Home"
- asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Atualize o nome do aplicativo do <footer> elemento. O exemplo a seguir usa o nome BlazorHosteddo aplicativo :
- © {DATE} - {DONOR NAME} - <a asp-area="" asp-page="/Privacy">Privacy</a>
+ © {DATE} - BlazorHosted - <a asp-area="" asp-page="/Privacy">Privacy</a>
No exemplo anterior, o espaço reservado {DATE} representa a data de direitos autorais em um aplicativo gerado a partir do Razor modelo de projeto Pages ou MVC.
Para fazer com que o Privacy link leve a uma página de privacidade (Razor Páginas), adicione uma página de privacidade ao Server projeto.
Pages/Privacy.cshtml no projeto Server:
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
Para uma exibição de privacidade baseada em MVC, crie uma exibição de privacidade no Server projeto.
View/Home/Privacy.cshtml no projeto Server:
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
Home No controlador do aplicativo MVC, retorne a exibição.
Adicione o seguinte código ao Controllers/HomeController.cs:
public IActionResult Privacy()
{
return View();
}
Se você importar arquivos de um aplicativo doador, certifique-se de atualizar todos os namespaces nos arquivos para corresponder ao Server do projeto (por exemplo, BlazorHosted.Server).
Importe os ativos estáticos para o projeto Server a partir da pasta wwwroot do projeto doador:
-
wwwroot/csspasta e conteúdos -
wwwroot/jspasta e conteúdos -
wwwroot/libpasta e conteúdos
Se o projeto doador for criado a partir de um modelo de projeto ASP.NET Core e os arquivos não forem modificados, você poderá copiar toda wwwroot a pasta do projeto doador para o Server projeto e remover o favicon arquivo de ícone.
Advertência
Evite colocar o ativo estático nas Client pastas e Serverwwwroot . Se o mesmo arquivo estiver presente em ambas as pastas, uma exceção será lançada porque os ativos estáticos compartilham o mesmo caminho raiz da Web. Portanto, hospede um ativo estático em qualquer uma das wwwroot pastas, não em ambas.
Depois de adotar a configuração anterior, incorpore componentes Razor em páginas ou vistas do projeto Server. Use as orientações nas seguintes seções deste artigo:
- Renderizar componentes numa página ou vista com o Auxiliar de Etiquetas de Componente
- Renderizar componentes numa página ou visualização com um seletor CSS
Renderizar componentes em uma página ou exibição com o Auxiliar de Tag de Componente
Depois de configurar a solução, incluindo a configuração adicional, o Auxiliar de Tag de Componente suporta dois modos de renderização para renderizar um componente de um Blazor WebAssembly aplicativo em uma página ou exibição:
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página. Para evitar usar o namespace completo para o componente Counter com o Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), adicione uma diretiva @using para o namespace do projeto cliente Pages. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No projeto Server, Pages/RazorPagesCounter1.cshtml:
@page
@using BlazorHosted.Client.Pages
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter1. O componente pré-renderizado Counter é incorporado na página.
RenderMode Configura se o componente:
- É pré-renderizado na página.
- É renderizado como HTML estático na página ou se inclui as informações necessárias para inicializar um Blazor aplicativo a partir do agente do usuário.
Para obter mais informações sobre o Auxiliar de Tag de Componente, incluindo parâmetros de passagem e RenderMode configuração, consulte Auxiliar de Tag de Componente no ASP.NET Core.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Definir conteúdo filho por meio de um fragmento de renderização
O Auxiliar de Tag de Componente não suporta receber um RenderFragment delegado para o conteúdo de filho (por exemplo, param-ChildContent="..."). Recomendamos criar um componente Razor (.razor) que faça referência ao componente que desejas renderizar, juntamente com o conteúdo filho que queres passar. Em seguida, invoca o componente Razor da página ou visão.
Certifique-se de que os componentes pré-renderizados de nível superior não sejam cortados na publicação
Se um Auxiliar de Tag de Componente fizer referência direta a um componente de uma biblioteca que está sujeito a remoção no processo de publicação, o componente poderá ser removido durante a publicação porque não há referências a ele a partir do código do aplicativo cliente. Como resultado, o componente não é pré-renderizado, deixando um ponto em branco na saída. Se isso ocorrer, instrua o trimmer a preservar o componente de biblioteca ao adicionar um atributo DynamicDependency a qualquer classe na aplicação cliente. Para preservar um componente chamado SomeLibraryComponentToBePreserved, adicione o seguinte a qualquer componente:
@using System.Diagnostics.CodeAnalysis
@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All,
typeof(SomeLibraryComponentToBePreserved))]
A abordagem anterior geralmente não é necessária porque o aplicativo geralmente pré-renderiza seus componentes (que não são cortados), o que, por sua vez, faz referência a componentes de bibliotecas (fazendo com que eles também não sejam cortados). Use DynamicDependency explicitamente apenas para pré-renderizar um componente de biblioteca diretamente quando a biblioteca estiver sujeita a otimização.
Renderizar componentes numa página ou visualização com um seletor CSS
Depois de configurar a solução, incluindo a configuração adicional, adicione componentes raiz ao Client projeto de uma solução hospedada Blazor WebAssembly no arquivo Program.cs. No exemplo a seguir, o componente Counter é declarado como um componente raiz com um seletor CSS que seleciona o elemento cujo id corresponde a counter-component. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No arquivo Program.cs do projeto Client, adicione o namespace para os componentes do projeto Razor ao topo do arquivo:
using BlazorHosted.Client.Pages;
Depois que o builder for estabelecido no Program.cs, adicione o Counter componente como um componente raiz:
builder.RootComponents.Add<Counter>("#counter-component");
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página.
No projeto Server, Pages/RazorPagesCounter2.cshtml:
@page
<div id="counter-component">Loading...</div>
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter2. O componente pré-renderizado Counter é incorporado na página.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Observação
O exemplo anterior lança um JSException se um Blazor WebAssembly aplicativo é pré-renderizado e integrado a um Razor aplicativo Pages ou MVC simultaneamente com o uso de um seletor CSS. Navegar para um dos componentes do Client projeto Razor ou navegar para uma página ou exibição do Server com um componente incorporado lança um ou mais JSException.
Esse comportamento é normal porque a pré-renderização e a integração de um Blazor WebAssembly aplicativo com componentes roteáveis Razor são incompatíveis com o uso de seletores CSS.
Se tens trabalhado com os exemplos nas seções anteriores e desejas apenas ver o seletor CSS funcionar na tua aplicação de exemplo, comenta a especificação do componente raiz do projeto no arquivo AppClient.
- builder.RootComponents.Add<App>("#app");
+ //builder.RootComponents.Add<App>("#app");
Navegue até a página ou exibição com o componente incorporado Razor que usa um seletor CSS (por exemplo, /razorpagescounter2 do exemplo anterior). A página ou exibição é carregada com o componente incorporado e o componente incorporado funciona conforme o esperado.
Manter o estado pré-renderizado
Sem guardar o estado pré-renderizado, o estado utilizado durante a pré-renderização é perdido e precisa ser recriado quando a aplicação estiver totalmente carregada. Se qualquer estado for configurado de forma assíncrona, a interface do usuário poderá piscar à medida que a interface do usuário pré-renderizada for substituída por espaços reservados temporários e, em seguida, totalmente renderizada novamente.
Para persistir o estado dos componentes pré-renderizados, use o Auxiliar de Marca de Estado do Componente Persistente (fonte de referência). Adicione a etiqueta do Auxiliar de etiquetas, <persist-component-state />, dentro da etiqueta de fecho </body> na página _Host de uma aplicação que pré-renderiza componentes.
Observação
Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Em Pages/_Host.cshtml aplicações Blazor que são WebAssembly pré-renderizadas (WebAssemblyPrerendered) numa aplicação hospedada Blazor WebAssembly :
<body>
...
<persist-component-state />
</body>
Decida qual estado deve persistir usando o serviço PersistentComponentState. PersistentComponentState.RegisterOnPersisting registra uma função de retorno para persistir o estado do componente antes que a aplicação seja pausada. O estado é recuperado quando o aplicativo é retomado. Faça a chamada no final do código de inicialização para evitar uma possível condição de concorrência durante o desligamento da aplicação.
No exemplo a seguir:
- O
{TYPE}espaço reservado representa o tipo de dados a serem persistidos (por exemplo,WeatherForecast[]). - O
{TOKEN}marcador de posição é uma cadeia de caracteres identificador de estado (por exemplo,fetchdata).
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
O exemplo a seguir é uma versão atualizada do componente FetchData em um aplicativo Blazor WebAssembly hospedado com base no modelo do projeto Blazor. O componente WeatherForecastPreserveState persiste o estado de previsão do tempo durante a pré-renderização e, em seguida, recupera esse estado para inicializar o componente. O Auxiliar de Marca de Estado do Componente Persistente persiste o estado do componente após todas as invocações de componentes.
Pages/WeatherForecastPreserveState.razor:
@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts = await WeatherForecastService.GetForecastAsync(
DateOnly.FromDateTime(DateTime.Now));
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
Ao inicializar componentes com o mesmo estado usado durante a pré-renderização, todas as etapas de inicialização dispendiosas são executadas apenas uma vez. A interface do usuário renderizada também corresponde à interface do usuário pré-renderizada, portanto, nenhuma cintilação ocorre no navegador.
O estado pré-renderizado persistente é transferido para o cliente, onde é usado para restaurar o estado do componente. Para pré-renderização em um aplicativo hospedado Blazor WebAssembly , os dados são expostos ao navegador e não devem conter informações confidenciais e privadas.
Recursos adicionais Blazor WebAssembly
- Suporte à pré-renderização com carregamento de assembly em modo "lazy"
-
Razor assuntos do ciclo de vida dos componentes que dizem respeito à pré-renderização
-
Inicialização de componentes (
OnInitialized{Async}) -
Após a renderização do componente (
OnAfterRender{Async}) - Reconexão com estado após a pré-renderização: embora o conteúdo da seção se concentre em Blazor Server e na SignalRreconexão com estado, o cenário para a pré-renderização em aplicativos hospedados Blazor WebAssembly (WebAssemblyPrerendered) envolve condições e abordagens semelhantes para impedir a execução do código do desenvolvedor duas vezes. Para preservar o estado durante a execução do código de inicialização na pré-renderização, consulte a seção Manter estado pré-renderizado deste artigo.
- Pré-renderização com JavaScript interop
-
Inicialização de componentes (
- Tópicos de autenticação e autorização que dizem respeito à pré-renderização
- Alojar e publicar ASP.NET Core Blazor WebAssembly
- Manipular erros: Pré-renderização
-
OnNavigateAsync é executado duas vezes ao pré-renderizar: Manipular eventos de navegação assíncrona com
OnNavigateAsync
A pré-renderização pode melhorar a Otimização para Motores de Busca (SEO) ao renderizar conteúdo para a resposta HTTP inicial que os motores de busca podem usar para calcular o ranking da página.
Configuração da solução
Configuração de pré-renderização
Para configurar a pré-renderização para uma aplicação hospedada Blazor WebAssembly :
Hospede o Blazor WebAssembly aplicativo em um aplicativo ASP.NET Core. Uma aplicação autónoma Blazor WebAssembly pode ser adicionada a uma solução ASP.NET Core ou pode usar uma aplicação hospedada Blazor WebAssembly criada a partir do Blazor WebAssembly modelo de projeto com a opção hospedada:
- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
BlazorHosted. - Shell de comandos da CLI do Visual Studio Code/.NET:
dotnet new blazorwasm -ho(use a opção-ho|--hosted). Use a-o|--output {LOCATION}opção para criar uma pasta para a solução e definir os namespaces de projeto da solução. Nos exemplos deste artigo, a solução é denominadaBlazorHosted(dotnet new blazorwasm -ho -o BlazorHosted).
Para os exemplos neste artigo, o namespace do projeto cliente é
BlazorHosted.Client, e o namespace do projeto do servidor éBlazorHosted.Server.- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
Exclua o
wwwroot/index.htmlBlazor WebAssemblyClient arquivo do projeto.Client No projeto, exclua as seguintes linhas em
Program.cs:- builder.RootComponents.Add<App>("#app"); - builder.RootComponents.Add<HeadOutlet>("head::after");Adicione
_Host.cshtmle_Layout.cshtmlarquivos à Server pasta doPagesprojeto. Você pode obter os arquivos de um projeto criado a partir do modelo Blazor Server usando o Visual Studio ou usando o CLI do .NET com odotnet new blazorserver -o BlazorServercomando em um shell de comando (a opção-o BlazorServercria uma pasta para o projeto). Depois de colocar os arquivos na Server pasta doPagesprojeto, faça as seguintes alterações nos arquivos.Importante
O uso de uma página de layout (
_Layout.cshtml) com um Auxiliar de Tag de Componente para um HeadOutlet componente é necessário para controlar<head>o conteúdo, como o título da página (PageTitle componente) e outros elementos de cabeçalho (HeadContent componente). Para obter mais informações, consulte Controlar o conteúdo do cabeçote em aplicativos ASP.NET CoreBlazor.Faça as seguintes alterações no
_Layout.cshtmlarquivo:Atualize o
Pagesnamespace na parte superior do arquivo para corresponder ao namespace das Server páginas do aplicativo. O{APP NAMESPACE}marcador de posição no exemplo seguinte representa o namespace das páginas da aplicação doadora que forneceu o ficheiro_Layout.cshtml.Suprimir.
- @namespace {APP NAMESPACE}.PagesAdicione:
@namespace BlazorHosted.Server.PagesAdicione uma diretiva
@usingpara o projeto Client na parte superior do arquivo:@using BlazorHosted.ClientAtualize os links de folha de estilo para apontar para as folhas de estilo do projeto WebAssembly. No exemplo a seguir, o namespace do projeto cliente é
BlazorHosted.Client. O espaço reservado{APP NAMESPACE}representa o namespace da aplicação doadora que forneceu o ficheiro_Layout.cshtml. Atualize o Auxiliar de Tag do Componente (<component>) do componenteHeadOutletpara pré-renderizar.Suprimir.
- <link href="css/site.css" rel="stylesheet" /> - <link href="{APP NAMESPACE}.styles.css" rel="stylesheet" /> - <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />Adicione:
<link href="css/app.css" rel="stylesheet" /> <link href="BlazorHosted.Client.styles.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />Observação
Deixe o
<link>elemento que solicita a folha de estilo do Bootstrap (css/bootstrap/bootstrap.min.css) no lugar.Atualize a origem do Blazor script para usar o script do lado Blazor WebAssembly do cliente:
Suprimir.
- <script src="_framework/blazor.server.js"></script>Adicione:
<script src="_framework/blazor.webassembly.js"></script>
No ficheiro
_Host.cshtml:Altere o
Pagesnamespace para o Client do projeto. O marcador de posição{APP NAMESPACE}representa o namespace das páginas da aplicação doadora que forneceu o ficheiro_Host.cshtml.Suprimir.
- @namespace {APP NAMESPACE}.PagesAdicione:
@namespace BlazorHosted.ClientAtualize o
render-modedo Auxiliar de Tag de Componente para pré-renderizar o componente raizAppcom WebAssemblyPrerendered:Suprimir.
- <component type="typeof(App)" render-mode="ServerPrerendered" />Adicione:
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />Importante
A pré-renderização não é suportada para endpoints de autenticação (segmento de caminho
/authentication/). Para obter mais informações, consulte ASP.NET Core Blazor WebAssembly cenários de segurança adicionais.
No mapeamento de ponto de extremidade do Server projeto no
Program.cs, altere o fallback doindex.htmlarquivo para a_Host.cshtmlpágina:Suprimir.
- app.MapFallbackToFile("index.html");Adicione:
app.MapFallbackToPage("/_Host");Se os projetos Client e Server usarem um ou mais serviços comuns durante a pré-renderização, fatore os registros de serviço em um método que pode ser chamado de ambos os projetos. Para obter mais informações, consulte injeção de dependência do ASP.NET CoreBlazor.
Execute o projeto Server. O aplicativo Blazor WebAssembly hospedado é pré-renderizado pelo projeto Server para clientes.
Configuração para incorporar Razor componentes em páginas ou vistas
As secções e exemplos a seguir para integrar Razor componentes da aplicação ClientBlazor WebAssembly em páginas ou vistas da aplicação servidor exigem configuração adicional.
O Server projeto deve ter os seguintes arquivos e pastas.
Razor Páginas:
Pages/Shared/_Layout.cshtmlPages/Shared/_Layout.cshtml.cssPages/_ViewImports.cshtmlPages/_ViewStart.cshtml
MVC:
Views/Shared/_Layout.cshtmlViews/Shared/_Layout.cshtml.cssViews/_ViewImports.cshtmlViews/_ViewStart.cshtml
Importante
O uso de uma página de layout (_Layout.cshtml) com um Auxiliar de Tag de Componente para um HeadOutlet componente é necessário para controlar <head> o conteúdo, como o título da página (PageTitle componente) e outros elementos de cabeçalho (HeadContent componente). Para obter mais informações, consulte Controlar o conteúdo do cabeçote em aplicativos ASP.NET CoreBlazor.
Os arquivos anteriores podem ser obtidos gerando um aplicativo a partir dos modelos de projeto ASP.NET Core usando:
- Novas ferramentas de criação de projetos do Visual Studio.
- Abrir um shell de comando e executar
dotnet new webapp -o {PROJECT NAME}(Razor Pages) oudotnet new mvc -o {PROJECT NAME}(MVC). A opção-o|--outputcom um valor para o espaço reservado{PROJECT NAME}fornece um nome para o aplicativo e cria uma pasta para o aplicativo.
Atualize os namespaces no arquivo importado _ViewImports.cshtml para corresponder àqueles em uso pelo Server projeto que recebe os arquivos.
Pages/_ViewImports.cshtml (Razor Páginas):
@using BlazorHosted.Server
@namespace BlazorHosted.Server.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Views/_ViewImports.cshtml (MVC):
@using BlazorHosted.Server
@using BlazorHosted.Server.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Atualize o arquivo de layout importado, que é Pages/Shared/_Layout.cshtml para Razor Pages ou Views/Shared/_Layout.cshtml MVC.
Primeiro, exclua o título e a folha de estilo do projeto doador, que está RPDonor.styles.css no exemplo a seguir. O {PROJECT NAME} espaço reservado representa o nome do aplicativo do projeto doador.
- <title>@ViewData["Title"] - {PROJECT NAME}</title>
- <link rel="stylesheet" href="~/RPDonor.styles.css" asp-append-version="true" />
Inclua os Client estilos do projeto no arquivo de layout. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client. O <title> elemento pode ser atualizado ao mesmo tempo.
Coloque as seguintes linhas no conteúdo do ficheiro de layout:
<title>@ViewData["Title"] - BlazorHosted</title>
<link href="css/app.css" rel="stylesheet" />
<link rel="stylesheet" href="BlazorHosted.Client.styles.css" asp-append-version="true" />
<component type="typeof(HeadOutlet)" render-mode="WebAssemblyPrerendered" />
O layout importado contém dois Home (Index página) e Privacy links de navegação. Para fazer com que os Home links apontem para o aplicativo hospedado Blazor WebAssembly , altere os hiperlinks:
- <a class="navbar-brand" asp-area="" asp-page="/Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Em um arquivo de layout MVC:
- <a class="navbar-brand" asp-area="" asp-controller="Home"
- asp-action="Index">{PROJECT NAME}</a>
+ <a class="navbar-brand" href="/">BlazorHosted</a>
- <a class="nav-link text-dark" asp-area="" asp-controller="Home"
- asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Atualize o nome do aplicativo do <footer> elemento. O exemplo a seguir usa o nome BlazorHosteddo aplicativo :
- © {DATE} - {DONOR NAME} - <a asp-area="" asp-page="/Privacy">Privacy</a>
+ © {DATE} - BlazorHosted - <a asp-area="" asp-page="/Privacy">Privacy</a>
No exemplo anterior, o espaço reservado {DATE} representa a data de direitos autorais em um aplicativo gerado a partir do Razor modelo de projeto Pages ou MVC.
Para fazer com que o Privacy link leve a uma página de privacidade (Razor Páginas), adicione uma página de privacidade ao Server projeto.
Pages/Privacy.cshtml no projeto Server:
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
Para uma exibição de privacidade baseada em MVC, crie uma exibição de privacidade no Server projeto.
View/Home/Privacy.cshtml no projeto Server:
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
Home No controlador do aplicativo MVC, retorne a exibição.
Adicione o seguinte código ao Controllers/HomeController.cs:
public IActionResult Privacy()
{
return View();
}
Se você importar arquivos de um aplicativo doador, certifique-se de atualizar todos os namespaces nos arquivos para corresponder ao Server do projeto (por exemplo, BlazorHosted.Server).
Importe os ativos estáticos para o projeto Server a partir da pasta wwwroot do projeto doador:
-
wwwroot/csspasta e conteúdos -
wwwroot/jspasta e conteúdos -
wwwroot/libpasta e conteúdos
Se o projeto doador for criado a partir de um modelo de projeto ASP.NET Core e os arquivos não forem modificados, você poderá copiar toda wwwroot a pasta do projeto doador para o Server projeto e remover o favicon arquivo de ícone.
Advertência
Evite colocar o ativo estático nas Client pastas e Serverwwwroot . Se o mesmo arquivo estiver presente em ambas as pastas, uma exceção será lançada porque o ativo estático em cada pasta compartilha o mesmo caminho raiz da Web. Portanto, hospede um ativo estático em qualquer wwwroot pasta, não em ambas.
Depois de adotar a configuração anterior, incorpore componentes Razor em páginas ou vistas do projeto Server. Use as orientações nas seguintes seções deste artigo:
- Renderizar componentes numa página ou vista com o Auxiliar de Etiquetas de Componente
- Renderizar componentes numa página ou visualização com um seletor CSS
Renderizar componentes em uma página ou exibição com o Auxiliar de Tag de Componente
Depois de configurar a solução, incluindo a configuração adicional, o Auxiliar de Tag de Componente suporta dois modos de renderização para renderizar um componente de um Blazor WebAssembly aplicativo em uma página ou exibição:
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página. Para evitar usar o namespace completo para o componente Counter com o Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), adicione uma diretiva @using para o namespace do projeto cliente Pages. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No projeto Server, Pages/RazorPagesCounter1.cshtml:
@page
@using BlazorHosted.Client.Pages
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter1. O componente pré-renderizado Counter é incorporado na página.
RenderMode Configura se o componente:
- É pré-renderizado na página.
- É renderizado como HTML estático na página ou se inclui as informações necessárias para inicializar um Blazor aplicativo a partir do agente do usuário.
Para obter mais informações sobre o Auxiliar de Tag de Componente, incluindo parâmetros de passagem e RenderMode configuração, consulte Auxiliar de Tag de Componente no ASP.NET Core.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Definir conteúdo filho por meio de um fragmento de renderização
O Auxiliar de Tag de Componente não suporta receber um RenderFragment delegado para o conteúdo de filho (por exemplo, param-ChildContent="..."). Recomendamos criar um componente Razor (.razor) que faça referência ao componente que desejas renderizar, juntamente com o conteúdo filho que queres passar. Em seguida, invoca o componente Razor da página ou visão.
Certifique-se de que os componentes pré-renderizados de nível superior não sejam cortados na publicação
Se um Auxiliar de Tag de Componente fizer referência direta a um componente de uma biblioteca que está sujeito a remoção no processo de publicação, o componente poderá ser removido durante a publicação porque não há referências a ele a partir do código do aplicativo cliente. Como resultado, o componente não é pré-renderizado, deixando um ponto em branco na saída. Se isso ocorrer, instrua o trimmer a preservar o componente de biblioteca ao adicionar um atributo DynamicDependency a qualquer classe na aplicação cliente. Para preservar um componente chamado SomeLibraryComponentToBePreserved, adicione o seguinte a qualquer componente:
@using System.Diagnostics.CodeAnalysis
@attribute [DynamicDependency(DynamicallyAccessedMemberTypes.All,
typeof(SomeLibraryComponentToBePreserved))]
A abordagem anterior geralmente não é necessária porque o aplicativo geralmente pré-renderiza seus componentes (que não são cortados), o que, por sua vez, faz referência a componentes de bibliotecas (fazendo com que eles também não sejam cortados). Use DynamicDependency explicitamente apenas para pré-renderizar um componente de biblioteca diretamente quando a biblioteca estiver sujeita a otimização.
Renderizar componentes numa página ou visualização com um seletor CSS
Depois de configurar a solução, incluindo a configuração adicional, adicione componentes raiz ao Client projeto de uma solução hospedada Blazor WebAssembly no arquivo Program.cs. No exemplo a seguir, o componente Counter é declarado como um componente raiz com um seletor CSS que seleciona o elemento cujo id corresponde a counter-component. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No arquivo Program.cs do projeto Client, adicione o namespace para os componentes do projeto Razor ao topo do arquivo:
using BlazorHosted.Client.Pages;
Depois que o builder for estabelecido no Program.cs, adicione o Counter componente como um componente raiz:
builder.RootComponents.Add<Counter>("#counter-component");
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página.
No projeto Server, Pages/RazorPagesCounter2.cshtml:
@page
<div id="counter-component">Loading...</div>
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter2. O componente pré-renderizado Counter é incorporado na página.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Observação
O exemplo anterior lança um JSException se um Blazor WebAssembly aplicativo é pré-renderizado e integrado a um Razor aplicativo Pages ou MVC simultaneamente com o uso de um seletor CSS. Navegar para um dos componentes do Client projeto Razor ou navegar para uma página ou exibição do Server com um componente incorporado lança um ou mais JSException.
Esse comportamento é normal porque a pré-renderização e a integração de um Blazor WebAssembly aplicativo com componentes roteáveis Razor são incompatíveis com o uso de seletores CSS.
Se tens trabalhado com os exemplos nas seções anteriores e desejas apenas ver o seletor CSS funcionar na tua aplicação de exemplo, comenta a especificação do componente raiz do projeto no arquivo AppClient.
- builder.RootComponents.Add<App>("#app");
+ //builder.RootComponents.Add<App>("#app");
Navegue até a página ou exibição com o componente incorporado Razor que usa um seletor CSS (por exemplo, /razorpagescounter2 do exemplo anterior). A página ou exibição é carregada com o componente incorporado e o componente incorporado funciona conforme o esperado.
Manter o estado pré-renderizado
Sem guardar o estado pré-renderizado, o estado utilizado durante a pré-renderização é perdido e precisa ser recriado quando a aplicação estiver totalmente carregada. Se qualquer estado for configurado de forma assíncrona, a interface do usuário poderá piscar à medida que a interface do usuário pré-renderizada for substituída por espaços reservados temporários e, em seguida, totalmente renderizada novamente.
Para resolver esses problemas, Blazor oferece suporte à persistência do estado em uma página pré-renderizada usando o Auxiliar de Tag de Estado do Componente Persistente. Adicione a tag do Auxiliar de tag, <persist-component-state />, dentro da tag de fechamento </body> .
Pages/_Layout.cshtml:
<body>
...
<persist-component-state />
</body>
Decida qual estado deve persistir usando o serviço PersistentComponentState. PersistentComponentState.RegisterOnPersisting registra uma função de retorno para persistir o estado do componente antes que a aplicação seja pausada. O estado é recuperado quando o aplicativo é retomado. Faça a chamada no final do código de inicialização para evitar uma possível condição de concorrência durante o desligamento da aplicação.
O exemplo a seguir é uma versão atualizada do componente FetchData em um aplicativo Blazor WebAssembly hospedado com base no modelo do projeto Blazor. O componente WeatherForecastPreserveState persiste o estado de previsão do tempo durante a pré-renderização e, em seguida, recupera esse estado para inicializar o componente. O Auxiliar de Marca de Estado do Componente Persistente persiste o estado do componente após todas as invocações de componentes.
Pages/WeatherForecastPreserveState.razor:
@page "/weather-forecast-preserve-state"
@implements IDisposable
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(DateTime.Now);
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
Ao inicializar componentes com o mesmo estado usado durante a pré-renderização, todas as etapas de inicialização dispendiosas são executadas apenas uma vez. A interface do usuário renderizada também corresponde à interface do usuário pré-renderizada, portanto, nenhuma cintilação ocorre no navegador.
O estado pré-renderizado persistente é transferido para o cliente, onde é usado para restaurar o estado do componente. Para pré-renderização em um aplicativo hospedado Blazor WebAssembly , os dados são expostos ao navegador e não devem conter informações confidenciais e privadas.
Recursos adicionais Blazor WebAssembly
- Suporte à pré-renderização com carregamento de assembly em modo "lazy"
-
Razor assuntos do ciclo de vida dos componentes que dizem respeito à pré-renderização
-
Inicialização de componentes (
OnInitialized{Async}) -
Após a renderização do componente (
OnAfterRender{Async}) - Reconexão com estado após a pré-renderização: embora o conteúdo da seção se concentre em Blazor Server e na SignalRreconexão com estado, o cenário para a pré-renderização em aplicativos hospedados Blazor WebAssembly (WebAssemblyPrerendered) envolve condições e abordagens semelhantes para impedir a execução do código do desenvolvedor duas vezes. Para preservar o estado durante a execução do código de inicialização na pré-renderização, consulte a seção Manter estado pré-renderizado deste artigo.
- Pré-renderização com JavaScript interop
-
Inicialização de componentes (
- Tópicos de autenticação e autorização que dizem respeito à pré-renderização
- Alojar e publicar ASP.NET Core Blazor WebAssembly
A pré-renderização pode melhorar a Otimização para Motores de Busca (SEO) ao renderizar conteúdo para a resposta HTTP inicial que os motores de busca podem usar para calcular o ranking da página.
Configuração da solução
Configuração de pré-renderização
Para configurar a pré-renderização para uma aplicação hospedada Blazor WebAssembly :
Hospede o Blazor WebAssembly aplicativo em um aplicativo ASP.NET Core. Uma aplicação autónoma Blazor WebAssembly pode ser adicionada a uma solução ASP.NET Core ou pode usar uma aplicação hospedada Blazor WebAssembly criada a partir do Blazor WebAssembly modelo de projeto com a opção hospedada:
- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
BlazorHosted. - Shell de comandos da CLI do Visual Studio Code/.NET:
dotnet new blazorwasm -ho(use a opção-ho|--hosted). Use a-o|--output {LOCATION}opção para criar uma pasta para a solução e definir os namespaces de projeto da solução. Nos exemplos deste artigo, a solução é denominadaBlazorHosted(dotnet new blazorwasm -ho -o BlazorHosted).
Para os exemplos neste artigo, o namespace do projeto cliente é
BlazorHosted.Client, e o namespace do projeto do servidor éBlazorHosted.Server.- Visual Studio: Na caixa de diálogo Informações adicionais , marque a caixa de seleção ASP.NET Core Hosted ao criar o Blazor WebAssembly aplicativo. Nos exemplos deste artigo, a solução é denominada
Exclua o
wwwroot/index.htmlBlazor WebAssemblyClient arquivo do projeto.Client No projeto, exclua a seguinte linha em
Program.cs:- builder.RootComponents.Add<App>("#app");Adicione um
Pages/_Host.cshtmlarquivo à Server pasta doPagesprojeto. Você pode obter um arquivo_Host.cshtmlde um projeto criado a partir do modelo Blazor Server com o comandodotnet new blazorserver -o BlazorServerem um shell de comando (a opção-o BlazorServercria uma pasta para o projeto). Depois de colocar o arquivoPages/_Host.cshtmlno projeto Server da solução hospedada Blazor WebAssembly, faça as seguintes alterações no arquivo:Forneça uma
@usingdiretiva para o Client projeto (por exemplo,@using BlazorHosted.Client).Atualize os links de folha de estilo para apontar para as folhas de estilo do projeto WebAssembly. No exemplo a seguir, o namespace do projeto cliente é
BlazorHosted.Client:- <link href="css/site.css" rel="stylesheet" /> - <link href="_content/BlazorServer/_framework/scoped.styles.css" rel="stylesheet" /> + <link href="css/app.css" rel="stylesheet" /> + <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />Observação
Deixe o
<link>elemento que solicita a folha de estilo do Bootstrap (css/bootstrap/bootstrap.min.css) no lugar.Atualize o
render-modedo Auxiliar de Tag de Componente para pré-renderizar o componente raizAppcom WebAssemblyPrerendered:- <component type="typeof(App)" render-mode="ServerPrerendered" /> + <component type="typeof(App)" render-mode="WebAssemblyPrerendered" />Atualize a origem do Blazor script para usar o script do lado Blazor WebAssembly do cliente:
- <script src="_framework/blazor.server.js"></script> + <script src="_framework/blazor.webassembly.js"></script>
No projeto
Startup.Configure, altere o fallback do ficheiro Server para a páginaindex.html.Startup.cs:- endpoints.MapFallbackToFile("index.html"); + endpoints.MapFallbackToPage("/_Host");Se os projetos Client e Server usarem um ou mais serviços comuns durante a pré-renderização, fatore os registros de serviço em um método que pode ser chamado de ambos os projetos. Para obter mais informações, consulte injeção de dependência do ASP.NET CoreBlazor.
Execute o projeto Server. O aplicativo Blazor WebAssembly hospedado é pré-renderizado pelo projeto Server para clientes.
Configuração para incorporar Razor componentes em páginas ou vistas
As seções e exemplos a seguir neste artigo para incorporar Razor componentes do aplicativo cliente Blazor WebAssembly em páginas ou exibições do aplicativo servidor exigem configuração adicional.
Use um ficheiro de layout padrão Pages ou MVC no projeto RazorServer. O Server projeto deve ter os seguintes arquivos e pastas.
Razor Páginas:
Pages/Shared/_Layout.cshtmlPages/_ViewImports.cshtmlPages/_ViewStart.cshtml
MVC:
Views/Shared/_Layout.cshtmlViews/_ViewImports.cshtmlViews/_ViewStart.cshtml
Obtenha os ficheiros anteriores de uma aplicação criada a partir do modelo de projeto Razor Pages ou MVC. Para obter mais informações, consulte Tutorial: Introdução ao Razor Pages in ASP.NET Core ou Introdução ao ASP.NET Core MVC.
Atualize os namespaces no arquivo importado _ViewImports.cshtml para corresponder àqueles em uso pelo Server projeto que recebe os arquivos.
Atualize o arquivo de layout importado (_Layout.cshtml) para incluir os Client estilos do projeto. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client. O <title> elemento pode ser atualizado ao mesmo tempo.
Pages/Shared/_Layout.cshtml (Razor Páginas) ou Views/Shared/_Layout.cshtml (MVC):
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>@ViewData["Title"] - DonorProject</title>
+ <title>@ViewData["Title"] - BlazorHosted</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
+ <link href="css/app.css" rel="stylesheet" />
+ <link href="BlazorHosted.Client.styles.css" rel="stylesheet" />
</head>
O layout importado contém links de navegação Home e Privacy. Para fazer com que o Home link aponte para o aplicativo hospedado Blazor WebAssembly , altere o hiperlink:
- <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Em um arquivo de layout MVC:
- <a class="nav-link text-dark" asp-area="" asp-controller="Home"
- asp-action="Index">Home</a>
+ <a class="nav-link text-dark" href="/">Home</a>
Para fazer com que o Privacy link leve a uma página de privacidade, adicione uma página de privacidade ao Server projeto.
Pages/Privacy.cshtml no projeto Server:
@page
@model BlazorHosted.Server.Pages.PrivacyModel
@{
}
<h1>Privacy Policy</h1>
Se preferir uma visualização de privacidade baseada em MVC, crie uma exibição de privacidade no Server projeto.
View/Home/Privacy.cshtml:
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
No controlador Home, retorne a visualização.
Controllers/HomeController.cs:
public IActionResult Privacy()
{
return View();
}
Importe os ativos estáticos para o projeto Server a partir da pasta wwwroot do projeto doador:
-
wwwroot/csspasta e conteúdos -
wwwroot/jspasta e conteúdos -
wwwroot/libpasta e conteúdos
Se o projeto doador for criado a partir de um modelo de projeto ASP.NET Core e os arquivos não forem modificados, você poderá copiar toda wwwroot a pasta do projeto doador para o Server projeto e remover o favicon arquivo de ícone.
Advertência
Evite colocar o ativo estático nas Client pastas e Serverwwwroot . Se o mesmo arquivo estiver presente em ambas as pastas, uma exceção será lançada porque o ativo estático em cada pasta compartilha o mesmo caminho raiz da Web. Portanto, hospede um ativo estático em qualquer wwwroot pasta, não em ambas.
Renderizar componentes em uma página ou exibição com o Auxiliar de Tag de Componente
Depois de configurar a solução, incluindo a configuração adicional, o Auxiliar de Tag de Componente suporta dois modos de renderização para renderizar um componente de um Blazor WebAssembly aplicativo em uma página ou exibição:
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página. Para evitar usar o namespace completo para o componente Counter com o Component Tag Helper ({ASSEMBLY NAME}.Pages.Counter), adicione uma diretiva @using para o namespace do projeto cliente Pages. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No projeto Server, Pages/RazorPagesCounter1.cshtml:
@page
@using BlazorHosted.Client.Pages
<component type="typeof(Counter)" render-mode="WebAssemblyPrerendered" />
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter1. O componente pré-renderizado Counter é incorporado na página.
RenderMode Configura se o componente:
- É pré-renderizado na página.
- É renderizado como HTML estático na página ou se inclui as informações necessárias para inicializar um Blazor aplicativo a partir do agente do usuário.
Para obter mais informações sobre o Auxiliar de Tag de Componente, incluindo parâmetros de passagem e RenderMode configuração, consulte Auxiliar de Tag de Componente no ASP.NET Core.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Renderizar componentes numa página ou visualização com um seletor CSS
Depois de configurar a solução, incluindo a configuração adicional, adicione componentes raiz ao Client projeto de uma solução hospedada Blazor WebAssembly no Program.cs. No exemplo a seguir, o componente Counter é declarado como um componente raiz com um seletor CSS que seleciona o elemento cujo id corresponde a counter-component. No exemplo a seguir, o Client namespace do projeto é BlazorHosted.Client.
No âmbito do Program.cs do projeto, adicione o namespace Client para os componentes Razor do projeto no topo do arquivo.
using BlazorHosted.Client.Pages;
Depois que o builder for estabelecido no Program.cs, adicione o Counter componente como um componente raiz:
builder.RootComponents.Add<Counter>("#counter-component");
No seguinte exemplo das Razor Páginas, o componente Counter é renderizado numa página. Para tornar o componente interativo, o Blazor WebAssembly script é incluído na seção de renderização da página.
No projeto Server, Pages/RazorPagesCounter2.cshtml:
@page
<div id="counter-component">Loading...</div>
@section Scripts {
<script src="_framework/blazor.webassembly.js"></script>
}
Execute o projeto Server. Navegue até a página Razor no /razorpagescounter2. O componente pré-renderizado Counter é incorporado na página.
Trabalho adicional pode ser necessário dependendo dos recursos estáticos que os componentes usam e como as páginas de layout são organizadas em um aplicativo. Normalmente, os scripts são adicionados à seção de renderização de uma página ou de uma exibição Scripts, e as folhas de estilo <head> são adicionadas ao conteúdo do elemento do layout.
Observação
O exemplo anterior lança um JSException se um Blazor WebAssembly aplicativo é pré-renderizado e integrado a um Razor aplicativo Pages ou MVC simultaneamente com um seletor CSS. Navegar para um dos componentes do Client projeto Razor gera a seguinte exceção:
Microsoft.JSInterop.JSException: Não foi possível encontrar nenhum elemento correspondente ao seletor '#counter-component'.
Esse comportamento é normal porque a pré-renderização e a integração de um Blazor WebAssembly aplicativo com componentes roteáveis Razor são incompatíveis com o uso de seletores CSS.
Recursos adicionais Blazor WebAssembly
- Suporte à pré-renderização com carregamento de assembly em modo "lazy"
-
Razor assuntos do ciclo de vida dos componentes que dizem respeito à pré-renderização
-
Inicialização de componentes (
OnInitialized{Async}) -
Após a renderização do componente (
OnAfterRender{Async}) - Reconexão com estado após a pré-renderização: embora o conteúdo da seção se concentre em Blazor Server e na SignalRreconexão com estado, o cenário para a pré-renderização em aplicativos hospedados Blazor WebAssembly (WebAssemblyPrerendered) envolve condições e abordagens semelhantes para impedir a execução do código do desenvolvedor duas vezes. Para preservar o estado durante a execução do código de inicialização na pré-renderização, consulte a seção Manter estado pré-renderizado deste artigo.
- Pré-renderização com JavaScript interop
-
Inicialização de componentes (
- Tópicos de autenticação e autorização que dizem respeito à pré-renderização
- Alojar e publicar ASP.NET Core Blazor WebAssembly