.Net Core 3 IStringLocalizer.DenganCulture (CultureInfo) sudah usang

9

Saya telah memutakhirkan proyek dari .Net Core 2.2 ke .Net Core 3.0.

Setelah mencoba memperbaiki semua peringatan dan kesalahan, saya sekarang mencoba untuk mendanai solusi untuk peringatan ini:

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

Saya menggunakan ini untuk mengubah bahasa situs web per pengguna yang masuk. Saya memiliki implementasi ini untuk mengubah budaya situs web per pengguna:

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

Dan ini adalah kelas dummy yang hanya menampung .resxfile untuk terjemahan:

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

Saya tidak dapat menemukan apa pun di web yang merujuk pada cara mengatasi peringatan ini kecuali untuk diskusi tentang github yang tampaknya belum memiliki solusi.

Adakah orang lain yang menemukan peringatan ini dan menemukan solusi untuknya?

Liran Friedman
sumber

Jawaban:

4

Sudah disebutkan di sana kode sumber di sini

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

Inilah cara mereka menggunakan .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);
   }

Pembaruan: Pendekatan ini bekerja sampai kami dapat memiliki pengumuman resmi dari Microsoft

Anda dapat membuat layanan seperti ini

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

Kemudian di startup.cs Anda

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

Anda dapat melihat kode lengkap saya di sini

Tony Ngo
sumber
Saya telah memperbarui pertanyaan saya dengan kode yang saya gunakan. Bisakah Anda melihatnya? Karena itu tidak terlihat kompatibel dengan solusi Anda.
Liran Friedman
@LiranFriedman, di mana Anda mendapatkan ICultureLocalizer? Saya mencoba mencari antarmuka itu tetapi saya tidak dapat menemukannya
Tony Ngo
Bisakah Anda jelaskan bagaimana budaya berubah per pengguna? Setiap pengguna memilih bahasa pilihannya di profilnya. Juga, bagaimana saya bisa mengecek untuk melihat apakah itu berfungsi?
Liran Friedman
Bagi mereka yang menggunakan ini di aplikasi konsol - penting untuk digunakan CurrentUICulturekarena CurrentCulturetampaknya tidak berpengaruh StringLocalizer. Jika menggunakan dalam aplikasi web, Anda dapat menggunakan services.Configure<RequestLocalizationOptions>untuk menyesuaikan perilaku untuk mendeteksi bahasa permintaan pengguna saat ini, tetapi perhatikan standar Microsoft - header, cookie, apa pun - untuk deteksi bahasa otomatis. Untuk alasan ini saya lebih suka menyesuaikan diri RequestCultureProvidersdengan mekanisme yang saya ketahui sendiri untuk mendeteksi bahasa pengguna.
JustAMartin