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

Blazor Server中OnInitializedAsync()第二次调用时路由值丢失问题

Blazor Server路由本地化:解决OnInitializedAsync中路由值丢失问题

核心问题原因

  • ServerPrerendered模式:会执行两次OnInitializedAsync——第一次服务器预渲染时能拿到路由值,但建立SignalR连接后第二次初始化时,预渲染的路由上下文不会自动传递,导致路由值为空。
  • Server模式:仅初始化一次,但如果未正确从请求上下文或导航管理器获取路由,也无法拿到语言参数。

解决方案

1. 跨渲染阶段获取路由参数

通过IHttpContextAccessor(服务器端预渲染时)和NavigationManager(客户端连接后)结合,覆盖两种场景:

@inject NavigationManager NavManager
@inject IHttpContextAccessor HttpContextAccessor

@code {
    private string? _languageCode;

    protected override async Task OnInitializedAsync()
    {
        // 服务器预渲染阶段:从HttpContext读取路由
        if (HttpContextAccessor.HttpContext != null)
        {
            var routeData = HttpContextAccessor.HttpContext.GetRouteData();
            _languageCode = routeData.Values["lang"]?.ToString();
        }
        // 客户端连接阶段:从导航URL解析路由
        else
        {
            var uriSegments = new Uri(NavManager.Uri).PathSegments;
            // 假设路由格式为 /{lang}/{page},取第二个路径段
            if (uriSegments.Count > 1)
                _languageCode = uriSegments[1];
        }

        // 应用本地化设置
        if (!string.IsNullOrEmpty(_languageCode))
        {
            var targetCulture = new CultureInfo(_languageCode);
            CultureInfo.DefaultThreadCurrentCulture = targetCulture;
            CultureInfo.DefaultThreadCurrentUICulture = targetCulture;
        }

        await base.OnInitializedAsync();
    }
}

2. 用PersistentComponentState传递预渲染状态

如果需要在两次初始化之间保留语言参数(针对ServerPrerendered模式),可以用PersistentComponentState存储状态:

@inject PersistentComponentState PersistentState
@inject IHttpContextAccessor HttpContextAccessor

@code {
    private string? _languageCode;

    protected override void OnInitialized()
    {
        // 尝试读取预渲染时保存的语言参数
        if (!PersistentState.TryTakeFromJson<string>("LanguageCode", out var storedLang))
        {
            // 预渲染阶段获取并保存参数
            if (HttpContextAccessor.HttpContext != null)
            {
                var routeData = HttpContextAccessor.HttpContext.GetRouteData();
                _languageCode = routeData.Values["lang"]?.ToString();
                PersistentState.PersistAsJson("LanguageCode", _languageCode);
            }
        }
        else
        {
            // 客户端连接阶段读取保存的参数
            _languageCode = storedLang;
        }

        // 应用本地化设置...
    }
}

3. 本地化服务配置

在Program.cs中正确配置本地化,确保只使用路由参数作为语言来源:

// 添加本地化服务
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

// 配置请求本地化
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo("en"),
        new CultureInfo("zh-CN")
        // 新增其他支持的语言
    };

    options.DefaultRequestCulture = new RequestCulture("en");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    // 清除默认的语言检测提供者,只使用路由参数
    options.RequestCultureProviders.Clear();
});

// 启用请求本地化中间件(放在UseRouting之后)
app.UseRequestLocalization();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:28:19