【问题标题】:.Net Core 3 IStringLocalizer.WithCulture(CultureInfo) is obsolete.Net Core 3 IStringLocalizer.WithCulture(CultureInfo) 已过时
【发布时间】:2019-10-10 06:15:05
【问题描述】:

我已将一个项目从 .Net Core 2.2 升级到 .Net Core 3.0。

在尝试修复所有警告和错误后,我现在正试图找到解决此警告的方法:

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

我正在使用它来更改每个登录用户的网站语言。 我有这个实现来改变每个用户的网站文化:

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

这是一个虚拟类,它只保存.resx 文件用于翻译:

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

我在网上找不到任何关于如何解决此警告的内容,除了这个似乎还没有解决方案的 discussion on github

有没有其他人偶然发现了这个警告并找到了解决方案?

【问题讨论】:

  • 你有没有想过这个问题?阅读接受的答案,我不确定这如何解决我认为您所问的问题。就我而言,我需要编写自己的ViewLocalizer,所以我从微软在 Github 上的实现开始,它仍然有 WithCulture 方法,所以我想知道我应该如何解决它。

标签: c# asp.net-core .net-core asp.net-core-mvc asp.net-core-3.0


【解决方案1】:

已经在源代码中提到了here

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

这是他们在.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);
   }

更新:在我们得到 Microsoft 的正式公告之前,这种方法一直有效

你可以创建这样的服务

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

然后在你的 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?}");
            });
        }
    }

你可以查看我的完整代码here

【讨论】:

  • 我已经用我正在使用的代码更新了我的问题。你能看一下吗?因为它看起来与您的解决方案不兼容。
  • @LiranFriedman 你从哪里获得 ICultureLocalizer ?我正在尝试搜索该界面,但我找不到它
  • 您能否解释一下每个用户的文化是如何变化的?每个用户在其个人资料中选择他/她的首选语言。另外,我如何检查它是否有效?
  • 对于那些在控制台应用程序中使用它的人 - 使用CurrentUICulture 很重要,因为CurrentCulture 似乎对StringLocalizer 没有影响。如果在 Web 应用程序中使用,您可以使用 services.Configure&lt;RequestLocalizationOptions&gt; 调整行为以检测当前用户的请求语言,但请注意 Microsoft 默认设置 - 标头、cookie 等 - 用于自动语言检测。出于这个原因,我更喜欢将RequestCultureProviders 调整为我自己已知的检测用户语言的机制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
相关资源
最近更新 更多