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
相关产品推荐
相关产品推荐

