Interactividad Switch Blazor
Cambiar un proyecto existente de Power Portals Pro de un modo de interactividad a otro implica una serie de ediciones en Program.cs, App.razor, el .Client proyecto y (al añadir interactividad) las páginas de la Cuenta. El propio marco no necesita ningún cambio, solo el cableado del anfitrión. Los pasos siguientes cubren las transiciones más comunes.
Propina
Si tus personalizaciones están en un número reducido de páginas, el camino de menor fricción es andamiar un proyecto nuevo en el modo objetivo y copiar tus personalizaciones. Comparar tu host actual con una referencia recién generada también es útil para buscar una discrepancia tras un cambio manual.
dotnet new powerportalspro -o MyPortal-Reference --interactivity Auto
Servidor → WebAssembly o Auto
Estos pasos añaden WebAssembly a un host solo de servidor. Las mismas modificaciones se aplican tanto si apuntas solo a WebAssembly como a Auto — las únicas diferencias son qué métodos de construcción encadenas Program.cs y qué modos App.razor de renderizado devuelves. Ambos se llaman por paso.
1. Convertir el . Proyecto cliente a una aplicación WebAssembly
Abre .Client/MyApp.Client.csproj y cambia el SDK de Microsoft.NET.Sdk.Razor a Microsoft.NET.Sdk.BlazorWebAssembly. Añadir el framework WebAssembly y los paquetes cliente 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>
Añade también el paquete .csproj de alojamiento WebAssembly en el servidor del servidor — proporciona el middleware que ofrece el paquete WASM:
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" />
2. Registrar componentes interactivos de WebAssembly en el servidor
En el servidor Program.cs, reemplaza el registro de componentes por las llamadas al constructor correspondientes. AddAuthenticationStateSerialization() serializa al usuario autenticado a través del límite Server→WASM para que la cascada AuthenticationState sea consistente en ambos tiempos de ejecución:
// Reemplazar
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// Con (Auto)
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
// O (WebAssembly)
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
3. Mapear el modo de renderizado de WebAssembly
Actualización app.MapRazorComponents<App>() para encadenar los endpoints de modo de renderizado correspondientes. La AddAdditionalAssemblies llamada ya apunta a los .Client ensamblajes _Imports en las plantillas, así que aquí no cambia:
// Auto
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
// WebAssembly
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(MyApp.Client._Imports).Assembly);
4. Actualizar el PageRenderMode de App.razor
En App.razor's PageRenderMode getter, devuelvo el nuevo modo de renderizado. Fija /Account/* primero InteractiveWebAssemblyRenderMode(prerender: false)y luego devuelve el valor predeterminado para todo lo demás:
// En el getter PageRenderMode de App.razor
if (HttpContext.Request.Path.StartsWithSegments("/Account"))
return new InteractiveWebAssemblyRenderMode(prerender: false);
// Auto
return new InteractiveAutoRenderMode();
// WebAssembly
return new InteractiveWebAssemblyRenderMode();
El pin de ruta de cuenta es necesario porque el del framework IAuthService solo está registrado en el grafo DI del cliente WASM. Sin el pin, el prerenderizado del servidor de Auto no se resuelve [Inject] IAuthService en una sesión en frío.
5. Añadir . Cliente/Program.cs
Crea una Program.cs en el .Client proyecto. Esto configura el host WebAssembly, se HttpClient registra con el gestor de reenvío de cookies (es decir, llamadas autenticadas desde el cliente WASM para /api/* ver la misma cookie de autenticación que el navegador) y llama AddPowerPortalsProWebClient para registrar los servicios del framework del lado WASM. La UserPowerPortalsProWebClient llamada prerecoge las cadenas de localización de corte cruzado al inicio, así que la primera pintura no parpadea el texto clave como respaldo:
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. Cambiar de post-formulario a endpoints de autenticación JSON
Los servidores de servidores se utilizan MapAdditionalIdentityEndpoints() para páginas de identidad de publicación de formularios. WebAssembly y los hosts Auto usan MapAuthEndpoints<TUser>() en su lugar — el .Clientwrapper de 's IAuthService llama a estos extremos JSON bajo /api/auth/*:
// Añade a la Program.cs del servidor (después de la app. UsePowerPortalsProWebServer)
app.MapAuthEndpoints<PortalUser>();
// Opcionalmente, intercambia los extremos de Identidad de forma por los JSON
// (borra la línea de abajo — solo la consumen las páginas de cuentas renderizadas por el servidor)
// app. MapAdditionalIdentityEndpoints();
Cuando el host ejecuta tanto páginas de cuenta de servidor como de WASM (poco común), ambos registros de endpoint pueden coexistir. Las plantillas predeterminadas eligen una u otra según el modo interactivo.
7. Mover las páginas de la cuenta a la . Proyecto del cliente
Power Portals Pro incluye dos conjuntos paralelos de páginas de cuenta, una para cada contexto de renderizado:
- Elimina las páginas renderizadas por el servidor debajo
Components/Account/Pages/y las clases auxiliares (IdentityRedirectManager,IdentityUserAccessor,IdentityComponentsEndpointRouteBuilderExtensions,CookieLoginController) del proyecto del servidor. - Añade las páginas de la cuenta WASM bajo
.Client/Pages/Account/. La forma más rápida es hacer andamios en un proyecto--interactivity Autonuevo y copiarlos — cubren Inicio de sesión, Registro, OlvidadaContraseña, ResetPassword, ConfirmaciónEmail, Inicio de sesión externo y toda la superficie Gestionar/*. - Si personalizas cualquiera de las páginas de cuenta renderizadas por el servidor (validación personalizada, campos adicionales), traslada esas personalizaciones a los equivalentes de WASM: implementan la misma experiencia de usuario en
IAuthServicelugar deUserManager.
8. Opcional — gestor de excepciones con alcance para /api/*
Cuando WebAssembly está en juego, se lanzan excepciones desde /api/* la necesidad de hacer el viaje de ida y vuelta al cliente WASM como problema RFC 9457+json para que el lado PowerPortalsProService del cliente pueda rehidratar el tipo CLR original. Las plantillas conectan esto con un ámbito UseExceptionHandler /api/* solo — la Página de Excepciones para Desarrolladores sigue gestionando errores de página renderizadas por el servidor en otros lugares:
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments("/api"),
branch => branch.UseExceptionHandler());
}
WebAssembly o servidor de → automática
Invierte los pasos anteriores:
- Suelta
AddInteractiveWebAssemblyComponents()yAddAuthenticationStateSerialization()desde el registro de componentes del servidor; solo conservaAddInteractiveServerComponents(). - Sustituye
.AddInteractiveWebAssemblyRenderMode()(y cualquierInteractiveServerRenderModeencadenado que esté a lo lado) por una entradaMapRazorComponents<App>()simple.AddInteractiveServerRenderMode(). - En
App.razor,PageRenderModesuelta el/Account/*pin y retornanew InteractiveServerRenderMode()para cada ruta interactiva. - Mueve las páginas de la cuenta de vuelta al proyecto servidor usando
Components/Account/Pages/elUserManagerpatrón -direct (o andamia un proyecto de servidor nuevo y cópialas). Vuelve a añadirIdentityRedirectManager/IdentityUserAccessory quita el.Client/Pages/Account/set. - Sustituye
app.MapAuthEndpoints<PortalUser>()porapp.MapAdditionalIdentityEndpoints(). - Cambia el
.ClientSDK del proyecto de nuevo aMicrosoft.NET.Sdk.Razor, elimina las referencias de paquetes WebAssembly y elimina.Client/Program.csy.Client/wwwroot/.
Ensamblaje Web Automático ↔
El switch más barato — el diseño del proyecto, los paquetes y las páginas de cuenta son idénticos entre ambos. Solo cambian tres cosas:
- En
App.razor,PageRenderModeintercambianew InteractiveAutoRenderMode()pornew InteractiveWebAssemblyRenderMode()(o viceversa) en la rama por defecto. El/Account/*pasador se mantiene igual en ambos modos. - En servidor
Program.cs, añadir o quitarAddInteractiveServerComponents()—AddRazorComponents()Auto lo necesita, solo WebAssembly no. - En el servidor
Program.cs, añadir o eliminar.AddInteractiveServerRenderMode()enMapRazorComponents<App>().
Verificación del cambio
Después de hacer los cambios:
- Construye la solución. La mayoría de los errores de cableado aparecen en tiempo de compilación: métodos de renderizado ausentes, tipos sin resolver o referencias a páginas de cuenta obsoletas.
- Iniciar y salir de sesión. La autenticación es lo más disruptivo que hay que cambiar: realizar todo el ciclo de Inicio de Sesión → Gestionar Perfil → Cerrar sesión para confirmar que los nuevos endpoints están correctamente cableados.
- Haz clic en una página interactiva. Un clic en una cuadrícula o editor demuestra que la interactividad está alcanzando el tiempo de ejecución adecuado. El modo servidor muestra una conexión SignalR en la pestaña WebSocket de las herramientas de desarrollo; WebAssembly muestra los archivos de ejecución en la
/_framework/pestaña de red. - Revisa el paquete WASM en la primera carga. Para los modos WebAssembly y Auto, la pestaña de red en una carga nueva (incógnita o caché borrada) debería mostrar los ensamblajes de ejecución + framework + portal que se están transmitiendo.
- Verifica las páginas de Cuenta/Gestionar. Cambios de perfil, cambios de contraseña y el inicio de sesión externo que enlaza cada uno a un punto final diferente — confirma que todo se complete correctamente.
Nota
Ten cuidado con las diferencias entre servicio y vida útil al mover servicios entre el servidor y el cliente WASM. El host WASM funciona como un único ámbito por sesión, pero los servicios de caché del framework se registran como singletons — si registras tu propio servicio como
Transienten el lado WASM, el estado por instancia reinicia silenciosamente cada resolución. ÚsaloSingletonen el lado WASM para cualquier servicio que mantenga estado mutable.
