如何在ResourceManager中找到可用的资源文化?

时间:2012-08-20 06:24:39

标签: c# .net localization

我有一种情况,我想为我的应用程序提供一个“可用语言”列表(顺便提一下,如果有任何可能性,它是一个ASP .NET MVC 3应用程序)。我认为我可以自动获取此列表,因为它应该只是构建中包含的resx文件(我不需要支持英国英语,德国奥地利或任何东西,只有英语或德语)我想出了我将在下面介绍的一个方案(作为单例实现,因为它是一种强化方法)。

问题在于,在某些机器上,它返回“阿拉伯语”,即使我没有这样的资源,并且在我的(因为我安装了VS 2012)它返回所有这些(这对我来说比返回两个真实更有意义文化加上阿拉伯语,但似乎ResourceManager并不是为了让我得到这些信息,所以我可能不应该抱怨)。这是方案......

(我有一个Strings.resx和一个Strings.de.resx文件)

IEnumerable<CultureInfo> cultures =
    CultureInfo.GetCultures(CultureTypes.NeutralCultures)
        .Where(c =>
                   {
                       // Exclude the invariant culture and then load up
                       // an arbitrary string so the resource manager
                       // loads a resource set, then get the set for the
                       // current culture specifically and it is, sometimes
                       // (I thought always but I was wrong) null if no
                       // set exists
                       if (c.LCID == CultureInfo.InvariantCulture.LCID)
                           return false;

                       var rm = Strings.ResourceManager;
                       rm.GetString("HELLO", c);
                       return rm.GetResourceSet(c, false, false) != null;
                   });

那么我想,好吧,我可以根据语言特定的目录是否存在这样做来实现:

var neutralCulture = new[]
{
    CultureInfo
        .CreateSpecificCulture(((NeutralResourcesLanguageAttribute)
                                Assembly
                                    .GetExecutingAssembly()
                                    .GetCustomAttributes(
                                        typeof (NeutralResourcesLanguageAttribute),
                                        false)[0])
                                .CultureName)
};

IEnumerable<CultureInfo> cultures =
    CultureInfo.GetCultures(CultureTypes.NeutralCultures)
        .Where(c => Directory.Exists(c.TwoLetterISOLanguageName))
        .Union(neutralCulture);

这“工作”(在很多方面它返回英语和德语),但我认为这不是一个非常稳定的方法,因为它容易出现随机问题,如有人创建一个文件夹并把它全部扔掉。我可以通过一些更明智的检查来缓解这些问题(where子句迫切需要更加复杂)但是这里的问题(最终)......

现在我正在考虑使用配置文件并保持完全简单,因为我不喜欢我所处的位置,但有更好的方法来做到这一点(或者:它可以自动完成安全的方式)?

2 个答案:

答案 0 :(得分:2)

我喜欢你的第二种自动检测方法。我想补充一点,你应该只做一次(在应用程序启动时或作为静态构造函数的一部分)并使其静态而不是每次请求支持的文化信息时计算它。

我认为配置方法也可以,但它不是真的自动化。我对这种情况的唯一想法是,如果你正在为一种语言进行本地化,那么它就不会潜入你的应用程序。话虽这么说,在那一点上添加一个配置值似乎是一件容易的事情(或忘记做)。

我不知道.NET Framework中内置的任何内容都可以通过方法调用为您提供此信息。

答案 1 :(得分:0)

我发现没有有效可靠的方法。

在我的每个程序集中,我编写了一个这样的代码,引用了支持的文化。这就是我们所能做的。添加本地化时,您必须记住更新此数组。

internal static class ThisAssembly
{
    static readonly string[] SupportedCultures = new string[] { "en-US", "de-DE", };
}

我也试过:

  • 枚举加载的卫星组件:没有方法;
  • 获取ResourceManager._resourceSets的值:已加载集的字典提供正确和无效的值。

但无济于事。