You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8 Preview 7新版Blazor模板中AuthenticationState无法正常工作

解决.NET 8 Preview 7混合Blazor模板认证预渲染错误

错误原因

该错误源于预渲染阶段(服务器端静态生成HTML时)没有JavaScript运行时环境,但RemoteAuthenticationService在初始化AuthenticationStateProvider时调用了JavaScript互操作(比如读取浏览器存储的认证令牌),违反了预渲染阶段不能执行JS互操作的限制。旧项目的解决方案失效,是因为.NET 8混合模板采用了新的交互式渲染模式配置逻辑,原有的_Host.cshtml路径判断方式不再适配新的路由体系。

解决方案

方案一:针对认证路径禁用预渲染

在Server项目的Program.cs中,为/authentication路径单独配置渲染规则,强制使用非预渲染的WebAssembly模式:

var builder = WebApplication.CreateBuilder(args);

// 常规混合模式路由配置
builder.Services.AddRazorComponents()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(Client._Imports).Assembly);

var app = builder.Build();

// 其他中间件配置(静态文件、路由等)
app.UseStaticFiles();
app.UseAntiforgery();

// 为认证路径单独设置渲染模式,禁用预渲染
app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/authentication"), subApp =>
{
    subApp.MapRazorComponents<Client.App>()
        .AddInteractiveWebAssemblyRenderMode(prerender: false);
});

// 其他路径使用默认混合模式
app.MapRazorComponents<Client.App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(Client._Imports).Assembly);

app.Run();

方案二:在认证组件上直接指定渲染模式

在登录、注册等认证相关组件(如Authentication.razor)顶部添加@rendermode指令,强制该组件使用非预渲染的WebAssembly模式:

@rendermode RenderMode.InteractiveWebAssembly(prerender: false)

<!-- 组件内容 -->

方案三:自定义认证状态提供器规避预渲染JS调用

创建一个包装原有认证服务的自定义AuthenticationStateProvider,预渲染时返回匿名状态,待客户端渲染完成后再获取真实认证状态:

  1. 定义自定义提供器:
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using System.Security.Claims;

public class PrerenderSafeAuthStateProvider : AuthenticationStateProvider
{
    private readonly RemoteAuthenticationService<RemoteAuthenticationState, RemoteUserAccount, OidcProviderOptions> _innerAuthService;
    private bool _isPrerendering = true;

    public PrerenderSafeAuthStateProvider(RemoteAuthenticationService<RemoteAuthenticationState, RemoteUserAccount, OidcProviderOptions> innerAuthService)
    {
        _innerAuthService = innerAuthService;
    }

    public void MarkAsPostPrerender()
    {
        _isPrerendering = false;
        NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
    }

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if (_isPrerendering)
        {
            // 预渲染时返回匿名身份
            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
        }

        return await _innerAuthService.GetAuthenticationStateAsync();
    }
}
  1. 在Server项目Program.cs中注册该提供器:
builder.Services.AddScoped<AuthenticationStateProvider, PrerenderSafeAuthStateProvider>();
  1. 在App.razor中触发状态更新:
@inject PrerenderSafeAuthStateProvider AuthStateProvider

<Router AppAssembly="@typeof(App).Assembly">
    <!-- 路由内容 -->
</Router>

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            AuthStateProvider.MarkAsPostPrerender();
            await base.OnAfterRenderAsync(firstRender);
        }
    }
}

内容的提问来源于stack exchange,提问作者user2657943

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:15:26