.Net Core 3 IStringLocalizer.WithCulture (CultureInfo) è obsoleto


9

Ho aggiornato un progetto da .Net Core 2.2 a .Net Core 3.0.

Dopo aver provato a correggere tutti gli avvisi e gli errori, ora sto cercando di finanziare una soluzione a questo avviso:

'IStringLocalizer.WithCulture(CultureInfo)' is obsolete: 'This method is obsolete.
 Use `CurrentCulture` and `CurrentUICulture` instead.'

Sto usando questo per cambiare la lingua del sito Web per l'utente che ha effettuato l'accesso. Ho questa implementazione per cambiare la cultura del sito Web per utente:

public class CultureLocalizer : ICultureLocalizer
{
    private readonly IStringLocalizer localizer;
    public CultureLocalizer(IStringLocalizerFactory factory)
    {
        var type = typeof(Resources.PageResources);
        var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
        localizer = factory.Create("PageResources", assemblyName.Name);
    }

    // if we have formatted string we can provide arguments         
    // e.g.: @Localizer.Text("Hello {0}", User.Name)
    public LocalizedString Get(string key, params string[] arguments)
    {
        return arguments == null ? localizer[key] : localizer[key, arguments];
    }

    public LocalizedString Get(Enum key, params string[] arguments)
    {
        return arguments == null ? localizer[key.ToString()] : localizer[key.ToString(), arguments];
    }

    public LocalizedString Get(CultureInfo culture, string key, params string[] arguments)
    {
        // This is obsolete
        return arguments == null ? localizer.WithCulture(culture)[key] : localizer.WithCulture(culture)[key, arguments];
    }

    public LocalizedString Get(CultureInfo culture, Enum key, params string[] arguments)
    {
        // This is obsolete
        return arguments == null ? localizer.WithCulture(culture)[key.ToString()] : localizer.WithCulture(culture)[key.ToString(), arguments];
    }
}

E questa è la classe fittizia che contiene solo il .resxfile per le traduzioni:

// dummy class for grouping localization resources
public class PageResources
{
}

Non sono riuscito a trovare nulla sul Web che si riferisca a come risolvere questo avviso, tranne per questa discussione su Github che sembra non avere ancora soluzione.

Qualcun altro si era imbattuto in questo avvertimento e aveva trovato una soluzione per esso?

Risposte:


4

È già menzionato nel codice sorgente qui

    /// <summary>
    /// Creates a new <see cref="IStringLocalizer"/> for a specific <see cref="CultureInfo"/>.
    /// </summary>
    /// <param name="culture">The <see cref="CultureInfo"/> to use.</param>
    /// <returns>A culture-specific <see cref="IStringLocalizer"/>.</returns>
    [Obsolete("This method is obsolete. Use `CurrentCulture` and `CurrentUICulture` instead.")]
    IStringLocalizer WithCulture(CultureInfo culture);

Ecco come si usano in .Net Core 3.0

public static void Main()  
   {
      // Display the name of the current thread culture.
      Console.WriteLine("CurrentCulture is {0}.", CultureInfo.CurrentCulture.Name);

      // Change the current culture to th-TH.
      CultureInfo.CurrentCulture = new CultureInfo("th-TH", false);
      Console.WriteLine("CurrentCulture is now {0}.", CultureInfo.CurrentCulture.Name);

      // Display the name of the current UI culture.
      Console.WriteLine("CurrentUICulture is {0}.", CultureInfo.CurrentUICulture.Name);

      // Change the current UI culture to ja-JP.
      CultureInfo.CurrentUICulture = new CultureInfo( "ja-JP", false );
      Console.WriteLine("CurrentUICulture is now {0}.", CultureInfo.CurrentUICulture.Name);
   }

Aggiornamento: questo approccio funziona fino a quando non avremo l'annuncio ufficiale da parte di Microsoft

Puoi creare un servizio come questo

public class LocalizationService
    {
        private readonly IStringLocalizer _localizer;

        public LocalizationService(IStringLocalizerFactory factory)
        {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create("SharedResource", assemblyName.Name);
        }

        public LocalizedString GetLocalizedHtmlString(string key)
        {
            return _localizer[key];
        }
    }

Quindi nel tuo startup.cs

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<LocalizationService>();
            services.AddLocalization(options => options.ResourcesPath = "Resources");

            services.Configure<RequestLocalizationOptions>(options =>
            {
                var supportedCultures = new[]
                {
                    new CultureInfo("en"),
                    new CultureInfo("nl")
                };

                options.DefaultRequestCulture = new RequestCulture(culture: "en", uiCulture: "en");
                options.SupportedCultures = supportedCultures;
                options.SupportedUICultures = supportedCultures;
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
                .AddDataAnnotationsLocalization(options =>
                {
                    options.DataAnnotationLocalizerProvider = (type, factory) =>
                    {
                        var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
                        return factory.Create("SharedResource", assemblyName.Name);
                    };
                });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            var localizationOption = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
            app.UseRequestLocalization(localizationOption.Value);

            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Puoi vedere il mio codice completo qui


Ho aggiornato la mia domanda con il codice che sto usando. Potresti per favore dare un'occhiata a questo? Perché non sembra compatibile con la tua soluzione.
Liran Friedman,

@LiranFriedman dove trovi ICultureLocalizer? Sto cercando di cercare quell'interfaccia ma non riesco a trovarla
Tony Ngo,

Potresti spiegare come cambia la cultura per utente? Ogni utente seleziona la sua lingua preferita nel suo profilo. Inoltre, come posso verificare per vedere se funziona?
Liran Friedman,

Per coloro che lo usano in un'app console - è importante usarlo CurrentUICultureperché CurrentCulturesembra non avere alcun effetto StringLocalizer. Se si utilizza in un'app Web, è possibile utilizzare services.Configure<RequestLocalizationOptions>per regolare il comportamento per rilevare la lingua delle richieste dell'utente corrente, ma prestare attenzione alle impostazioni predefinite di Microsoft (intestazioni, cookie, qualunque cosa) per il rilevamento automatico della lingua. Per questo motivo preferisco adattarmi RequestCultureProvidersal mio meccanismo noto per rilevare la lingua dell'utente.
JustAMartin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.