Interatividade Switch Blazor
Alternar um projeto existente do Power Portals Pro de um modo de interatividade para outro é uma série de edições em Program.cs, App.razor, no .Client projeto e (ao adicionar interatividade) nas páginas da Conta. A estrutura em si não precisa de nenhuma alteração — apenas a fiação do host precisa. Os passos abaixo cobrem as transições comuns.
Dica
Se suas personalizações ficam em poucas páginas, o caminho de menor atrito é estruturar um projeto novo no modo alvo e copiar suas personalizações. Comparar seu host atual com uma referência recém-gerada também é útil para buscar uma discrepância após uma troca manual.
dotnet new powerportalspro -o MyPortal-Reference --interactivity Auto
Server → WebAssembly ou Auto
Esses passos adicionam WebAssembly a um host apenas para servidor. As mesmas edições se aplicam, seja você mirando apenas em WebAssembly ou Auto — as únicas diferenças são quais métodos de construtor você encadeia Program.cs e quais modos App.razor de renderização retornam. Ambos são chamados a cada passo.
1. Converter o . Projeto cliente para um aplicativo WebAssembly
Abra .Client/MyApp.Client.csproj e mude o SDK de Microsoft.NET.Sdk.Razor para Microsoft.NET.Sdk.BlazorWebAssembly. Adicione o framework WebAssembly e os pacotes clientes Power Portals Pro:
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" />
<PackageReference Include="PowerPortalsPro.Web.Client" />
<PackageReference Include="PowerPortalsPro.Web.Blazor.FluentUI" />
<PackageReference Include="PowerPortalsPro.Web.Common" />
</ItemGroup>
</Project>
Adicione o pacote de hospedagem do lado do servidor WebAssembly também ao host .csproj do servidor — ele fornece o middleware que atende ao pacote WASM:
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
2. Registrar componentes interativos do WebAssembly no servidor
No servidor Program.cs, substitua o registro de componentes pelas chamadas de construtor correspondentes. AddAuthenticationStateSerialization() serializa o usuário autenticado através do limite Server→WASM para que a cascata AuthenticationState seja consistente em ambos os runtimes:
// Substituir
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// Com (Auto)
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
// Ou (WebAssembly)
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
3. Mapear o modo de renderização do WebAssembly
Atualização app.MapRazorComponents<App>() para encadear os endpoints correspondentes ao modo de renderização. A AddAdditionalAssemblies chamada já aponta para as .Client assembleias _Imports nos modelos, então não muda aqui:
// Auto
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
// WebAssembly
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
4. Atualizar o PageRenderMode do App.razor
Em App.razor's PageRenderMode getter, retorne o novo modo de renderização. Fixe /Account/* primeiro InteractiveWebAssemblyRenderMode(prerender: false)e depois retorne o padrão para todo o resto:
// No PageRenderMode do App.razor
if (HttpContext.Request.Path.StartsWithSegments("/Account"))
return new InteractiveWebAssemblyRenderMode(prerender: false);
// Auto
return new InteractiveAutoRenderMode();
// WebAssembly
return new InteractiveWebAssemblyRenderMode();
O pino Account-route é necessário porque o do framework IAuthService está registrado apenas no gráfico DI do cliente WASM. Sem o pin, o pré-render do lado do servidor do Auto não se resolve [Inject] IAuthService em uma sessão fria.
5. Adicionar . Cliente/Program.cs
Crie um Program.cs no .Client projeto. Isso configura o host WebAssembly, registra o HttpClient com o handler de encaminhamento de cookies (ou seja, chamadas autenticadas do cliente WASM para /api/* ver o mesmo cookie de autenticação do navegador) e chama AddPowerPortalsProWebClient para registrar os serviços do framework do lado WASM. A UserPowerPortalsProWebClient chamada pré-busca as strings de localização de corte cruzado na inicialização para que a primeira pintura não transmita texto com chave como recurso de recurso:
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.FluentUI.AspNetCore.Components;
using PowerPortalsPro.Web.Blazor.FluentUI;
using PowerPortalsPro.Web.Client;
using PowerPortalsPro.Web.Client.Services;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddFluentUIComponents();
builder.Services.AddSingleton<CookieCredentialsHandler>();
builder.Services.AddHttpClient("PowerPortalsPro", client =>
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<CookieCredentialsHandler>();
builder.Services.AddSingleton(sp =>
sp.GetRequiredService<IHttpClientFactory>().CreateClient("PowerPortalsPro"));
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
builder.Services.AddPowerPortalsProWebClient();
var app = builder.Build();
await app.UserPowerPortalsProWebClient(
LocalizationBaselines.Default.Concat(new[] { "app" }).ToArray());
await app.RunAsync();
6. Mudança do post-formulário para endpoints de autenticação JSON
Os hosts de servidor usam MapAdditionalIdentityEndpoints() páginas de identidade de postagem de formulário. WebAssembly e Auto hosts usam MapAuthEndpoints<TUser>() em vez disso — o .Clientwrapper de 's IAuthService chama esses endpoints JSON sob /api/auth/*:
// Adicione ao Program.cs do servidor (depois do app. UsePowerPortalsProWebServer)
app.MapAuthEndpoints<PortalUser>();
// Opcionalmente, troque os endpoints de Identidade do formulário por JSON
// (apague a linha abaixo — ela só é consumida por páginas de Conta renderizadas pelo servidor)
// app. MapAdditionalIdentityEndpoints();
Quando o host executa páginas de Conta do Servidor e WASM (incomum), ambos os registros de endpoint podem coexistir. Os modelos padrão escolhem um ou outro com base no modo de interatividade.
7. Mover as páginas da Conta para o arquivo . Projeto do cliente
Power Portals Pro vem com dois conjuntos paralelos de páginas de conta, uma para cada contexto de renderização:
- Exclua as páginas renderizadas pelo servidor abaixo
Components/Account/Pages/e as classes auxiliares (IdentityRedirectManager,IdentityUserAccessor,IdentityComponentsEndpointRouteBuilderExtensions,CookieLoginController) do projeto do servidor. - Adicione as páginas da conta WASM em
.Client/Pages/Account/. A maneira mais rápida é estruturar um projeto novo e--interactivity Autocopiá-los — eles cobrem Login, Registrar, EsquecidoSenha, ResetPassword, ConfirmarEmail, ExternalLogin e toda a superfície Gerenciar/*. - Se você personalizou qualquer uma das páginas de Conta renderizadas pelo servidor (validação personalizada, campos extras), porte essas customizações para os equivalentes do WASM — eles implementam a mesma experiência de usuário em
IAuthServicevez deUserManager.
8. Opcional — tratador de exceções com escopo para /api/*
Quando o WebAssembly está em jogo, exceções são lançadas da /api/* necessidade de fazer ida e volta ao cliente WASM como problema RFC 9457 + json para que o lado PowerPortalsProService do cliente possa reidratar o tipo CLR original. Os templates conectam isso com um escopo UseExceptionHandler apenas para /api/* — a Página de Exceção do Desenvolvedor ainda lida com erros de página renderizados pelo servidor em outros lugares:
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api"),
branch => branch.UseExceptionHandler());
}
WebAssembly ou Servidor de → Automática
Inverta os passos acima:
- Drop
AddInteractiveWebAssemblyComponents()eAddAuthenticationStateSerialization()do registro de componentes do servidor; apenas mantenhaAddInteractiveServerComponents(). - Substitua
.AddInteractiveWebAssemblyRenderMode()(e qualquer correnteInteractiveServerRenderModeao lado) por uma única.AddInteractiveServerRenderMode()polegadaMapRazorComponents<App>(). - Em
App.razor,PageRenderModesolte o/Account/*pino e retornenew InteractiveServerRenderMode()para cada rota interativa. - Mova as páginas da Conta de volta para o projeto servidor usando
Components/Account/Pages/oUserManagerpadrão -direct (ou faça uma estrutura em um projeto novo do servidor e copie para eles). RecoloqueIdentityRedirectManager/IdentityUserAccessore remova o.Client/Pages/Account/conjunto. - Substitua
app.MapAuthEndpoints<PortalUser>()porapp.MapAdditionalIdentityEndpoints(). - Altere o
.ClientSDK do projeto de volta paraMicrosoft.NET.Sdk.Razor, elimine as referências de pacotes WebAssembly e exclua.Client/Program.cse.Client/wwwroot/.
Auto ↔ WebAssembly
O switch mais barato — o layout do projeto, pacotes e páginas de Conta são idênticos entre os dois. Apenas três coisas mudam:
- Em
App.razor,PageRenderModetroquenew InteractiveAutoRenderMode()pornew InteractiveWebAssemblyRenderMode()(ou vice-versa) no ramo padrão. O/Account/*pino permanece o mesmo em ambos os modos. - No servidor
Program.cs, adicionar ou removerAddInteractiveServerComponents()—AddRazorComponents()o Auto precisa disso, só WebAssembly não. - No servidor
Program.cs, adicionar ou remover.AddInteractiveServerRenderMode()emMapRazorComponents<App>().
Verificando a Mudança
Após fazer as mudanças:
- Construa a solução. A maioria dos erros de fiação aparece na compilação — métodos de renderização ausentes, tipos não resolvidos ou referências de páginas de conta obsoletas.
- Faça login e saia. A autenticação é a coisa mais disruptiva a se mudar — exerça o ciclo completo de Login → Gerenciar Perfil → Logout para confirmar que os novos endpoints estão conectados corretamente.
- Clique em uma página interativa. Um clique em um botão em uma grade ou editor prova que a interatividade está alcançando o tempo de execução certo. O modo servidor mostra uma conexão SignalR na aba WebSocket das ferramentas de desenvolvimento; O WebAssembly mostra os arquivos de runtime abaixo
/_framework/na aba de rede. - Confira o pacote WASM na primeira carga. Para os modos WebAssembly e Auto, a aba de rede em uma carga nova (incógnita ou cache) deve mostrar o runtime + framework + portal assemblies que estão entrando.
- Verifique as páginas de Conta/Gerenciar. Mudanças de perfil, mudanças de senha e login externo vinculando cada um exercício a um endpoint diferente — confirme que tudo é concluído corretamente.
Nota
Fique atento a desajustes entre serviço e vida útil ao mover serviços entre o servidor e o cliente WASM. O host WASM roda como um único escopo por sessão, mas os serviços de cache do framework são registrados como singletons — se você registrar seu próprio serviço como
Transientdo lado WASM, o estado por instância reinicia silenciosamente toda resolução. UseSingletonno lado WASM para qualquer serviço que mantenha estado mutável.
