我有一种情况,我想为我的应用程序提供一个“可用语言”的列表(顺便说一下,如果有可能的话,它是一个 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 子句迫切需要更复杂),但这是问题(最后)......
现在我正在考虑只使用一个配置文件并保持它完全简单,因为我真的不喜欢我必须去的地方,但是有没有更好的方法来做到这一点(或者:它可以以安全的方式自动完成) ?