ASP.NET Core in .NET 8 的 I18N 多语言国际化

更新日期: 2024-08-11 阅读次数: 1356 字数: 613 分类: Windows

配置

例如,我想要的效果如下:

  • 支持中文和英文两门语言
  • 默认语言是英文
  • 翻译文件放到 Resources 目录下

上代码,在 Program.cs 入口文件中添加:

using Microsoft.AspNetCore.Localization;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddMvc()
    .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[] { "en", "zh" };
    options.SetDefaultCulture(supportedCultures[0])
        .AddSupportedCultures(supportedCultures)
        .AddSupportedUICultures(supportedCultures);
});

var app = builder.Build();

app.UseRequestLocalization();

...

具体说明可以参考:

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/make-content-localizable?view=aspnetcore-8.0

但是,官方文档写的也比较零碎,很难配置成功。还是以上面我的配置为准。

不同 Controller 和 View 目录的识别,对应关系

Views:

例如模板文件 Views/Home/About.cshtml, 在指定了 Resources 为存储目录的前提下,对应的翻译资源文件为下面两个文件,二选一:

  • Resources/Views/Home/About.fr.resx
  • Resources/Views.Home.About.fr.resx

我更喜欢第一种写法。

如果不指定 ResourcesPath,则 .resx 翻译资源文件,则可以放置在跟 cshtml 网页模板文件同一目录下。 但是我不喜欢这种搞法,不方便统一管理翻译资源。

Controllers:

类似的,在指定了 Resources 为存储目录的前提下,也支持两种配置目录:

  • Resources/Controllers/HomeController.fr.resx
  • Resources/Controllers.HomeController.fr.resx

如果不指定 ResourcesPath,则 .resx 翻译资源文件,则可以放置在项目根目录下,命名为 Controllers.HomeController.fr.resx。

对比之下,还是使用一个独立的 Resources 目录存储比较好。虽然 Views 方便了,但是 Controllers 不方便查找。

Fallback 机制

假设请求中 culture 参数为 fr-CA,那么 ASP 会依次查询下面三个资源文件,以第一个匹配作为返回:

  • Welcome.fr-CA.resx
  • Welcome.fr.resx
  • Welcome.resx

切换语言

参考:

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/select-language-culture?view=aspnetcore-8.0

只需要加上对应语言的 culture 查询参数,例如我实现的一个在线的二维码生成工具

切换不生效

https://stackoverflow.com/questions/77023829/localization-in-asp-net-core-net-7-not-working-at-all

app.UseRequestLocalization(app.Services.GetRequiredService<Microsoft.Extensions.Options.IOptions<RequestLocalizationOptions>>().Value);

现在英文可以显示了

可以简化为:参考 github

app.UseRequestLocalization();

SetDefaultCulture 无效

不设置 culture 和设置了 fr 的, 总是返回中文, 而非默认的英文。

实际上有个 3 个策略:

  • QueryStringRequestCultureProvider
  • CookieRequestCultureProvider
  • AcceptLanguageHeaderRequestCultureProvider

默认是 URL 中的 Query String。url 策略失效之后,估计走了浏览器语言 (即 AcceptLanguageHeaderRequestCultureProvider)。把浏览器语言改成 en 之后,就没有问题了。

.NET 8 的实现还是非常严谨的。

微信关注我哦 👍

大象工具微信公众号

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

tags: dotnet