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

文章目录

    配置

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

    • 支持中文和英文两门语言
    • 默认语言是英文
    • 翻译文件放到 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式