简体   繁体   中英

ASP.NET Core 3 Localization is only displaying keys

I am having some issues with getting text localization working in ASP.NET Core 3. Or rather, it was previously working, and since a mishap (not stashing changes and accidentally removing some of them) it no longer does. I'm sure I'm missing something basic, but I can work it out for the life of me.

I've got the following code blocks in place:

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);
            // ...
        }
    }

View:

@inject IHtmlLocalizer<Language> Localizer

...

@Localizer[Language.Login.SubmitButton]

I also have the following resx files containing the keys and text.
Resources\\Language.resx (also tried with name Language.en.resx to no avail)
Resources\\Language.fr.resx

All text is simply showing as the keys, regardless of whether it originates in an MVC View, Razor page, arbitrary class taking the localizer from DI, or attributes.

Any clue as to what I'm doing wrong? Thanks

So, ultimately it turns out that it's just the location of the Language.cs file that mattered here. Having it within the Resources folder was causing something to break (even without taking the namespace for that folder), whereas having it in the Project root works without issue.

I'm not exactly sure why this matters though - I'll edit this answer if I can find that out.

EDIT: Thanks to @Grimm for finding the answer. This does indeed appear to be a bug in .net core 3.1, as detailed on https://github.com/dotnet/aspnetcore/issues/17733

This could be a number of things.
You can try to rename you .resx file to:

Resources\\Language.en-US.resx

You can try to use something like @Localizer[Language.Login.SubmitButton].Value .

You can also try to create specific .resx files to each view:
Respecting the rules would be something like:

  • Create the .resx file with the view assembly name. Like: Views.Login.Index.en-US.resx
  • Inject the ViewLocalizer on your view
    @using Microsoft.AspNetCore.Mvc.Localization
    @inject IViewLocalizer Localizer
  • Then use it with string values, like: @Localizer["SubmitButton"].Value
    or even just @Localizer["SubmitButton"]

I would also change the startup code to something more straight foward

        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;
        });

Hope any of these help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM