Windows Server 2012 上的 Silverlight:抛出 CultureNotFoundException("zh-Hans-CN"),但机器已本地化为 zh-CN

Silverlight on Windows Server 2012: CultureNotFoundException("zh-Hans-CN") thrown, but machine is localized to zh-CN

我在 Windows Server 2012 机器上托管了一个 Silverlight 4 应用程序。服务器本地化为中文(简体),文化代码 zh-CN。我用以下 powershell 确认了这一点:

PS C:\> get-culture

LCID             Name             DisplayName
----             ----             -----------
2052             zh-CN            Chinese (Simplified, PRC)

get-UICulture 返回了 en-us,我怀疑这是因为我是从 en-us 机器进行 RDPing 的。我确认 UI 区域性已通过控制面板区域设置设置为 zh-CN。

当应用程序抛出异常时,似乎是在构建原始异常的详细信息时抛出 CultureNotFoundException。

简化示例:

List<string> items = { "a", "a" };
items.ToDictionary();

结果调用堆栈:

System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) // throws a CultureNotFoundException referencing zh-Hans-CN
System.Collections.Generic.Dictionary.Insert(...) // throws an ArgumentException "Duplicate Key Added"
System.Linq.Enumerable.ToDictionary(...)

我们通过 Silverlight 应用程序报告的异常的详细信息是

[Argument_CultureNotSupported]
参数: 
调试资源字符串不可用。密钥和参数通常提供足够的信息用以诊断该问题。请访问 http://go.microsoft.com/fwlink/?linkid=106663&Version=5.0.10411.00&File=mscorlib.dll&Key=Argument_CultureNotSupported
参数名: name
[Argument_CultureInvalidIdentifier]
参数: zh-Hans-CN
调试资源字符串不可用。密钥和参数通常提供足够的信息用以诊断该问题。请访问 http://go.microsoft.com/fwlink/?linkid=106663&Version=5.0.10411.00&File=mscorlib.dll&Key=Argument_CultureInvalidIdentifier

在 Silverlight 应用程序中,字符串资源已正确本地化为 zh-CN,但底层 .Net 异常构造代码似乎认为该应用程序位于 zh-Hans-CN。这会导致即使原始异常正确handled/suppressed/discarded.

也会报告异常

从 en-us 计算机浏览时,CultureNotFoundExceptions 不会作为异常过程的一部分抛出。相反,我在上面的示例中看到了真正的 "Duplicate Key added" ArgumentException。

我试图更改 web.config 全球化设置以包含

<system.web>
  <globalization culture="zh-CN" uiCulture="zh-CN" />
</system.web>

如所述here,行为没有明显变化。

我已经阅读了关于 zh-CN vs. zh-CHS vs. zh-Hans-CN vs. zh-Hans 的文章,对于一个不会说中文的人来说,这一切都令人费解。除了原来的 zh-CN 之外,我还向 Silverlight .xap 添加了 zh-Hans 资源,但这并没有改变行为。

我的直觉是 .Net 客户端核心正在寻找机器上未安装的 zh-Hans-CN 或 zh-Hans 资源,尽管机器肯定有 zh-CN 资源并且在 zh-CN 中我能想到的每一个测试。

我在这里的具体 objective 是为了防止抛出 CultureNotFoundExceptions,因为它们会导致转移注意力并且混淆由于其他有效的本地化异常而从代码中出现的真实异常。

非常感谢任何帮助!

这里发生了很多事情:

1) Silverlight 代码将 System.Thread.CurrentThread.CurrentCulture 设置为服务器的文化 zh-CN,即使未安装该语言包也是如此。

2) Silverlight 代码抛出有效的 .Net 库异常(我相信 InvalidOperationException)。

3) 在InvalidOperationException 的异常处理过程中,.Net 框架试图查找zh-CN(当前线程的当前文化)的本地化字符串。无法找到(未安装语言包),然后根据文化优先规则查找其他 language/culture 组合。当它最终到达 zh-Hans-CN(链中的最后一个)时,它最后一次失败并抛出 CultureNotSupportedException。

4) CultureNotFoundException 取代了原来的 InvalidOperationException,导致该异常被报告给 user/log。

最终的修复是删除将 Silverlight 的 CurrentThread.CurrentCulture 设置为服务器区域设置 的代码。这是以前黑客的产物,无论如何都已经过时了。