ASP.NET Core 3.1修改CurrentCulture及多语言API消息返回优化咨询
首先说你遇到的Thread.CurrentThread.CurrentCulture不生效的问题——在ASP.NET Core里直接改线程的文化设置其实不太靠谱,因为请求处理可能涉及线程池线程的复用,后续操作说不定就切换到其他线程了,之前的设置自然就丢了。而且ASP.NET Core本身有专门的请求级文化管理机制,正确的做法是通过HttpContext来设置:
HttpContext.RequestCulture = new RequestCulture(cultureInfo);
这样能确保整个请求生命周期里的文化设置都是有效的。
接下来是你问的无需数据库的多语言消息方案,ASP.NET Core官方推荐的资源文件(.resx)方案就完全符合你的需求,不用碰数据库,还能轻松管理多语言文本,具体步骤我给你拆解下:
1. 先创建资源文件
在项目里建个Resources文件夹,然后给每种语言做对应的资源文件:
SharedResources.resx:默认语言(比如你这里的英语),放所有通用的多语言键值对,比如Login-Success对应Login successful!,Login-failed对应Login failed, please check your credentials.SharedResources.fa-IR.resx:波斯语版本,对应键的翻译换成波斯语,比如Login-Success改成ورود موفقیتآمیز!
资源文件的使用很简单,直接在VS里编辑就行,键是统一的,不同语言文件对应不同翻译。
2. 配置本地化服务
在Program.cs里把本地化服务配置好,告诉程序资源文件在哪、支持哪些语言:
// 添加本地化服务,指定资源文件所在文件夹 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // 配置支持的文化 builder.Services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fa-IR") }; options.DefaultRequestCulture = new RequestCulture("en-US"); // 默认英语 options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); // 给控制器添加本地化支持 builder.Services.AddControllers() .AddDataAnnotationsLocalization();
3. 在控制器里用StringLocalizer
把IStringLocalizer注入到控制器里,就能直接根据当前请求文化获取对应的翻译了:
private readonly IStringLocalizer<SharedResources> _localizer; private readonly SignInManager<IdentityUser> _signInManager; // 构造函数注入 public YourAuthController(IStringLocalizer<SharedResources> localizer, SignInManager<IdentityUser> signInManager) { _localizer = localizer; _signInManager = signInManager; } [HttpPost("[action]/{languageid}")] public async Task<IActionResult> Login([FromBody] AccountViewModel model, [FromRoute] int languageid) { var result = await _signInManager.CheckPasswordSignInAsync(model.UserName, model.Password, true); // 根据languageid设置请求文化 var targetCulture = languageid == 1 ? new CultureInfo("fa-IR") : new CultureInfo("en-US"); HttpContext.RequestCulture = new RequestCulture(targetCulture); if (result.Succeeded) { return Ok(new { Result = true, Message = _localizer["Login-Success"] }); } return Ok(new { Result = false, Message = _localizer["Login-failed"] }); }
4. 进阶:自动识别请求文化
如果你不想每次都手动处理languageid参数,可以用RequestLocalizationMiddleware自动从URL参数、Cookie或者请求头里获取文化信息。只需要在Program.cs的中间件管道里加一句:
app.UseRequestLocalization();
这样用户访问的时候可以通过?culture=fa-IR参数,或者发送Accept-Language: fa-IR请求头,程序就会自动切换对应的文化,不用你在action里写判断逻辑了。
额外注意点
- 资源文件的命名空间要和项目根命名空间一致,不然可能找不到资源;如果不一样,也可以在配置的时候指定资源类型
- 这个方案完全适配API场景,不用依赖视图,返回的JSON里的消息会自动对应正确的语言
- 如果后续要加新语言,只需要新增对应的
.resx文件就行,不用改代码
内容的提问来源于stack exchange,提问作者Ali.Ahmadi

