配置
例如,我想要的效果如下:
- 支持中文和英文两门语言
- 默认语言是英文
- 翻译文件放到 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://www.sunzhongwei.com/tools4/qrcode?culture=zh
- 英文版: https://www.sunzhongwei.com/tools4/qrcode?culture=en
切换不生效
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 聊聊, 查看更多联系方式