我有一种情况,我想为我的应用程序提供一个“可用语言”列表(顺便提一下,如果有任何可能性,它是一个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子句迫切需要更加复杂)但是这里的问题(最终)......
现在我正在考虑使用配置文件并保持完全简单,因为我不喜欢我所处的位置,但有更好的方法来做到这一点(或者:它可以自动完成安全的方式)?
答案 0 :(得分:2)
我喜欢你的第二种自动检测方法。我想补充一点,你应该只做一次(在应用程序启动时或作为静态构造函数的一部分)并使其静态而不是每次请求支持的文化信息时计算它。
我认为配置方法也可以,但它不是真的自动化。我对这种情况的唯一想法是,如果你正在为一种语言进行本地化,那么它就不会潜入你的应用程序。话虽这么说,在那一点上添加一个配置值似乎是一件容易的事情(或忘记做)。
我不知道.NET Framework中内置的任何内容都可以通过方法调用为您提供此信息。
答案 1 :(得分:0)
我发现没有有效可靠的方法。
在我的每个程序集中,我编写了一个这样的代码,引用了支持的文化。这就是我们所能做的。添加本地化时,您必须记住更新此数组。
internal static class ThisAssembly
{
static readonly string[] SupportedCultures = new string[] { "en-US", "de-DE", };
}
我也试过:
ResourceManager._resourceSets
的值:已加载集的字典提供正确和无效的值。但无济于事。