Blazor Server动态切换语言时重写fr-CH区域设置失效求助
解决Blazor Server动态本地化fr-CH数字分隔符问题
针对静态本地化时修改CultureInfo数字格式有效,但动态切换语言后失效的问题,核心原因是动态切换时新加载的fr-CH文化是系统默认的,没有带上你定制的格式规则。以下是无需修改OS区域设置的可行方案:
1. 封装文化定制逻辑为可复用服务
创建一个服务来统一处理特定文化的格式定制,确保每次获取文化时都应用你的规则:
public interface ICultureCustomizer { CultureInfo GetCustomizedCulture(string cultureName); } public class CultureCustomizer : ICultureCustomizer { public CultureInfo GetCustomizedCulture(string cultureName) { var culture = new CultureInfo(cultureName); // 针对fr-CH定制数字分隔符,按需修改为你需要的格式 if (culture.Name.Equals("fr-CH", StringComparison.OrdinalIgnoreCase)) { culture.NumberFormat.NumberDecimalSeparator = "."; culture.NumberFormat.NumberGroupSeparator = "'"; // 可添加其他格式定制(如货币、日期) } return culture; } }
在Program.cs中注册该服务:
builder.Services.AddScoped<ICultureCustomizer, CultureCustomizer>();
2. 修改动态切换控制器,存储定制后的文化
在用于切换语言的CultureController中,注入定制服务,确保写入Cookie的是经过修改的文化:
[ApiController] [Route("[controller]/[action]")] public class CultureController : ControllerBase { private readonly ICultureCustomizer _cultureCustomizer; public CultureController(ICultureCustomizer cultureCustomizer) { _cultureCustomizer = cultureCustomizer; } public IActionResult SetCulture(string culture, string redirectUri) { if (!string.IsNullOrEmpty(culture)) { var customizedCulture = _cultureCustomizer.GetCustomizedCulture(culture); HttpContext.Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(customizedCulture)), new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } ); } return LocalRedirect(redirectUri); } }
3. 定制RequestLocalization中间件,确保请求级文化正确
Blazor Server的请求本地化依赖中间件,需要替换默认的文化提供器,让每次请求都获取定制后的文化:
// 在Program.cs中配置RequestLocalization builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fr-CH"), // 其他支持的文化 }; options.DefaultRequestCulture = new RequestCulture("en-US"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // 插入自定义Cookie文化提供器 var cultureCustomizer = builder.Services.BuildServiceProvider().GetRequiredService<ICultureCustomizer>(); options.RequestCultureProviders.Insert(0, new CustomCookieRequestCultureProvider(cultureCustomizer)); }); // 添加中间件(注意顺序,放在UseRouting之前) app.UseRequestLocalization();
自定义Cookie文化提供器实现:
public class CustomCookieRequestCultureProvider : CookieRequestCultureProvider { private readonly ICultureCustomizer _cultureCustomizer; public CustomCookieRequestCultureProvider(ICultureCustomizer cultureCustomizer) { _cultureCustomizer = cultureCustomizer; } public override async Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext) { var baseResult = await base.DetermineProviderCultureResult(httpContext); if (baseResult == null) return null; // 对每个文化应用定制规则 var customizedCultures = baseResult.Cultures .Select(c => _cultureCustomizer.GetCustomizedCulture(c)) .ToList(); var customizedUiCultures = baseResult.UiCultures .Select(c => _cultureCustomizer.GetCustomizedCulture(c)) .ToList(); return new ProviderCultureResult(customizedCultures, customizedUiCultures); } }
4. 组件生命周期中补全文化设置(可选)
由于Blazor Server的线程模型,组件渲染可能切换线程,可在组件初始化时再次设置定制文化,避免格式回退:
@inject ICultureCustomizer CultureCustomizer @code { protected override void OnInitialized() { var currentCultureName = CultureInfo.CurrentCulture.Name; var customizedCulture = CultureCustomizer.GetCustomizedCulture(currentCultureName); CultureInfo.CurrentCulture = customizedCulture; CultureInfo.CurrentUICulture = customizedCulture; } }
核心思路
通过将文化定制逻辑从单次初始化改为每次获取文化时动态应用,确保静态初始化和动态切换场景下,fr-CH的数字格式规则都能生效,完全无需修改OS区域设置。
内容的提问来源于stack exchange,提问作者neggenbe
相关产品推荐
相关产品推荐

