【问题标题】:Changing the language of an IStringLocalizer更改 IStringLocalizer 的语言
【发布时间】:2020-03-14 14:48:14
【问题描述】:

我试图在运行时动态设置IStringLocalizer 的语言。似乎可以做到这一点的唯一可用方法是IStringLocalizer.WithCulture。但是,尝试使用它会导致弃用警告。

public IStringLocalizer GetLocalizer(string locale) {
    this.localizerFactory.Create(typeof(CommonResources)).WithCulture(new CultureInfo(locale));
}

使用 ASP,我在处理来自其他来源(各种网络聊天 API)的用户交互的 IHostedService 中执行此操作。此服务需要符合管理员为聊天服务器或频道设置的语言(存储在数据库中)。

当前设置IStringLocalizer 语言的正确方法是什么?我应该完全使用另一个类吗?

【问题讨论】:

  • this SO 回答对您有帮助吗?
  • @SimonWilson 不幸的是,没有。在答案中,他们似乎只在应用程序开始时提供语言,以默认值和可用值集合的形式。如果他们以编程方式设置IStringLocalizer 的延迟,它会被很好地隐藏。此外,该示例是针对 ASP 应用程序的,这不是我的情况。
  • 此外,在评论中,OP 自己询问所提供的答案如何动态改变文化。
  • 可能您可以创建一个中间件,根据每个请求可以设置 currentCulture 或 UICulture。本地化程序会根据文化集自动解析字符串。

标签: c# .net-core internationalization


【解决方案1】:

应该这样做。在获取字符串值之前,您需要将CultureInfo.CurrentUICulture 设置为您想要的文化。

    private string GetStringValue(string stringName, string culture)
    {
        var specifiedCulture = new CultureInfo(culture);
        CultureInfo.CurrentCulture = specifiedCulture;
        CultureInfo.CurrentUICulture = specifiedCulture;
        var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" });
        var factory = new ResourceManagerStringLocalizerFactory(options, new LoggerFactory());
        var localizer = new StringLocalizer<RecipeController>(factory);
        return localizer[stringName];
    }

如果您有IStringLocalizer 的实例,您可以使用它而不是创建一个新实例。

【讨论】:

  • 曾经有方法 IStringLocalizer.WithCulture 但现在已经过时了。设置 CurrentCulture 和 CurrentUICulture 是微软文档中推荐的解决方案。
  • 答案对我来说似乎是正确的。 @LukášKmoch 的评论可能是正确的(我没有找到这样的文档),但我注意到 CurrentCulture 在这种情况下没有任何区别。 CurrentUICulture 似乎是要设置的主要内容。
【解决方案2】:

您可以编写自己的文化中间件,该中间件可以根据用户设置文化,也可以使用 Http Header Accept-Language

app.UseRequestLocalization(roptions =>
        {
            IList<CultureInfo> supportedCultures = new List<CultureInfo>
            {
                new CultureInfo("en-US"),
                new CultureInfo("fr"),
            };
            roptions.DefaultRequestCulture = new RequestCulture("en-US");
            roptions.SupportedCultures = supportedCultures;
            roptions.SupportedUICultures = supportedCultures;
            roptions.RequestCultureProviders.Add(new YourCustomCultureProvider());
        });

示例中间件

public class YourCustomCultureProvider : RequestCultureProvider
{
    public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException(nameof(httpContext));


        var culture = //Some Logic

        if (string.IsNullOrEmpty(culture))
        {
            // No values specified for either so no match
            return Task.FromResult((ProviderCultureResult)null);
        }

        var requestCulture = new ProviderCultureResult(culture);

        return Task.FromResult(requestCulture);
    }
}

如果对您有帮助,请参考此链接 - https://joonasw.net/view/aspnet-core-localization-deep-dive

【讨论】:

  • 根本没有 HTTP。正如我所说,我正在使用网络聊天 API,例如 Discord.Net。我不是使用ASP,这是不是一个网络应用程序。此外,您的解决方案没有提供在创建本地化程序时将任何对象传递给文化提供者的方法,它只能在配置应用程序时接收对象。
猜你喜欢
  • 1970-01-01
  • 2012-04-04
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-26
相关资源
最近更新 更多