ASP.NET Core 3 Localization 仅显示按键

ASP.NET Core 3 Localization is only displaying keys

我在让文本本地化在 ASP.NET Core 3 中工作时遇到了一些问题。或者更确切地说,它以前是工作的,但由于一次事故(没有隐藏更改并意外删除了其中的一些)它不再做。我确定我遗漏了一些基本的东西,但我可以终生解决。

我已经准备好以下代码块:

Startup.cs:

        private static readonly List<CultureInfo> SupportedCultures = new List<CultureInfo>
        {
            new CultureInfo("en"),
            new CultureInfo("fr")
        };

// ...

            services.AddMvc()
                .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; })
                .AddDataAnnotationsLocalization(options =>
                {
                    options.DataAnnotationLocalizerProvider = (type, factory) =>
                        factory.Create(typeof(Language));
                })
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                .AddRazorPagesOptions(options =>
                {
                    options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
                    options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
                });

            services.AddLocalization(o =>
            {
                o.ResourcesPath = "Resources";
            });

            services.Configure<RequestLocalizationOptions>(options =>
            {
                options.DefaultRequestCulture = new RequestCulture("en", "en");
                options.SupportedCultures = SupportedCultures;
                options.SupportedUICultures = SupportedCultures;
            });
// ...


            app.UseRequestLocalization(new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture("en"),
                SupportedCultures = SupportedCultures,
                SupportedUICultures = SupportedCultures,
                RequestCultureProviders = new List<IRequestCultureProvider>
                {
                    new QueryStringRequestCultureProvider(),
                    new CookieRequestCultureProvider()
                }
            });

Resources\Language.cs:

    public sealed class Language
    {

        public sealed class Login
        {
            public const string PageTitle          = nameof(Login) + nameof(PageTitle);
            public const string SubmitButton       = nameof(Login) + nameof(SubmitButton);
            public const string Username           = nameof(Login) + nameof(Username);
            // ...
        }
    }

查看:

@inject IHtmlLocalizer<Language> Localizer

...

@Localizer[Language.Login.SubmitButton]

我还有以下包含密钥和文本的 resx 文件。
Resources\Language.resx(也尝试使用名称 Language.en.resx 无济于事)
Resources\Language.fr.resx

所有文本都简单地显示为键,无论它是否源自 MVC 视图、Razor 页面、任意 class 从 DI 获取本地化程序或属性。

关于我做错了什么的任何线索?谢谢

这可能是多种情况。
您可以尝试将 .resx 文件重命名为:

Resources\Language.en-US.resx

你可以尝试使用类似@Localizer[Language.Login.SubmitButton].Value的东西。

您也可以尝试为每个视图创建特定的 .resx 文件:
遵守规则是这样的:

  • 使用视图程序集名称创建 .resx 文件。喜欢:Views.Login.Index.en-US.resx
  • 在您的视图中注入 ViewLocalizer
    @using Microsoft.AspNetCore.Mvc.Localization
    @inject IViewLocalizer Localizer
  • 然后将它与字符串值一起使用,例如: @Localizer["SubmitButton"].Value
    甚至只是 @Localizer["SubmitButton"]

我还会将启动代码更改为更直接的代码

        services.AddLocalization(options => options.ResourcesPath = "YourResourcesPath");

        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("pt-BR"),
                new CultureInfo("es-ES")
            };

            options.DefaultRequestCulture = new RequestCulture("YourDefaultCulture");
            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;
        });

希望以上内容对您有所帮助。

因此,最终证明 Language.cs 文件的位置在这里很重要。将它放在 Resources 文件夹中会导致某些东西被破坏(即使没有使用该文件夹的命名空间),而将它放在项目根目录中则没有问题。

我不太确定为什么这很重要 - 如果我能找到答案,我会编辑这个答案。

编辑:感谢@Grimm 找到答案。这确实是 .net core 3.1 中的一个错误,详见 https://github.com/dotnet/aspnetcore/issues/17733