Blazor Server URL含文化代码本地化:资源加载异常与按钮失效
Blazor Server带文化代码URL本地化的资源加载问题及解决方法
我在Blazor Server项目中实现带文化代码的URL本地化访问,支持类似https://example.com/en/counter(英文)、https://example.com/fr/counter(法文)、https://example.com/es/counter(西班牙文)的路由格式。页面本地化功能正常,但出现资源加载异常,导致Counter组件的按钮点击无响应。
经排查,问题源于使用CultureTemplatePageRouteModelConvention动态给所有页面路由添加{culture}前缀,导致Blazor框架文件、CSS等静态资源的请求路径被错误修改,无法正确加载。
原问题配置代码
// Add services to the container. builder.Services.AddRazorPages(options => { // decorate all page routes with {culture} e.g. @page "/{culture}..." // 注释下面这一行后,页面本地化失效,但资源加载的错误会消失 options.Conventions.Add(new CultureTemplatePageRouteModelConvention()); });
解决方案:自定义CookieRouteDataRequestCultureProvider
通过自定义CookieRouteDataRequestCultureProvider类解决问题,该类会优先从路由中获取文化代码;若路由未提供,则从URL路径中解析;如果都没有,则从Cookie读取已保存的文化信息,同时避免修改静态资源的路径。
完整代码如下:
public class CookieRouteDataRequestCultureProvider : RequestCultureProvider { public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) { string previousRouteCulture; string routeCulture = (string)httpContext.Request.RouteValues["culture"]; string urlCulture = httpContext.Request.Path.Value.Split('/')[1]; // 从路由参数获取文化代码 if (IsSupportedCulture(routeCulture)) { previousRouteCulture = routeCulture; RequestCulture requestCulture = new RequestCulture(routeCulture, routeCulture); // 取消注释后,左侧导航菜单在部分导航操作后会失效 SetThreadCulture(routeCulture); string cookieName = CookieRequestCultureProvider.DefaultCookieName; string cookieValue = CookieRequestCultureProvider.MakeCookieValue(requestCulture); httpContext.Response.Cookies.Append(cookieName, cookieValue); return Task.FromResult(new ProviderCultureResult(routeCulture)); } // 从URL路径解析文化代码 else if (IsSupportedCulture(urlCulture)) { SetThreadCulture(urlCulture); return Task.FromResult(new ProviderCultureResult(urlCulture)); } // 从Cookie读取或使用默认文化 else { CookieCultureProvider cookieCultureProvider = new CookieCultureProvider(Options.SupportedCultures.ToList()); string cultureFromCookieOrDefault = cookieCultureProvider.GetCultureFromCookie(httpContext); SetThreadCulture(cultureFromCookieOrDefault); return Task.FromResult(new ProviderCultureResult(cultureFromCookieOrDefault)); } } private static void SetThreadCulture(string routeCulture) { CultureInfo cultureInfo = CultureInfo.GetCultureInfo(routeCulture); Thread.CurrentThread.CurrentCulture = cultureInfo; Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(routeCulture); } /** * 验证文化代码是否在支持列表中 */ private bool IsSupportedCulture(string cultureCode) => !string.IsNullOrEmpty(cultureCode) && Options.SupportedCultures.Any(x => x.TwoLetterISOLanguageName.Equals( cultureCode, StringComparison.InvariantCultureIgnoreCase ) ); }
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

