特定于机器的 (??) 行为将 JSON 字符串解析为 DynamicJsonObject

Machine-specific (??) behavior parsing JSON string into DynamicJsonObject

我有一段代码 运行 在没有调试器的情况下按预期运行,但是当我在调试器下 运行 它时,它在一台机器上工作,在另一台机器上失败。两台机器的设置几乎相同:Windows 8,.NET Framework 4.5,Visual Studio 2013 Ultimate Update 4,我 运行 两台机器上的控制台应用程序相同。

代码解析此字符串包含 JSON:

{"success":true,"doAlternative":false,"errors":null,"content":null}

使用System.Web.Helpers进入动态对象:

dynamic result = Json.Decode(jsonString);

然后我访问结果对象的success字段:

if ( result.success != true )

在一台机器上(我提醒:问题是在调试器下 运行ning 时),这就可以了。另一方面,我得到 RuntimeBinderException:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException occurred
  _HResult=-2146233088
  _message='System.Web.Helpers.DynamicJsonObject' does not contain a definition for 'success'
  HResult=-2146233088
  IsTransient=false
  Message='System.Web.Helpers.DynamicJsonObject' does not contain a definition for 'success'
  Source=Microsoft.CSharp
  StackTrace:
       at Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError(CError pError)
  InnerException: 

在 "working" 机器上,当我在立即 window 中键入 result 时,我得到:

{System.Web.Helpers.DynamicJsonObject}
    base: {System.Web.Helpers.DynamicJsonObject}

在 "failing" 机器上,我得到这个:

{System.Web.Helpers.DynamicJsonObject}
    base: {System.Web.Helpers.DynamicJsonObject}
    _values: Count = 4

这是最奇怪的一点:在失败的机器上以立即 window 播放,第一次输入 result["success"] 会得到这个:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException occurred
  _HResult=-2146233088
  _message=Cannot apply indexing with [] to an expression of type 'System.Web.Helpers.DynamicJsonObject'
  HResult=-2146233088
  IsTransient=false
  Message=Cannot apply indexing with [] to an expression of type 'System.Web.Helpers.DynamicJsonObject'
  Source=Microsoft.CSharp
  StackTrace:
       at Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError(CError pError)
  InnerException: 

然后,再次输入 result["success"] 第二次,成功了!然后 result.success 也可以。它不会打扰我,但如果我不放置断点并且只是 运行 使用 F5 的应用程序,它会失败。

这种特定于机器调试器的行为令人恐惧 - 我害怕将存在此类问题的代码投入生产,(目前仅在调试器下观察到,但谁知道..?)有人可以请阐明这一点?

好的,我找到原因了 - here.

转到工具 > 选项 > 调试和检查 仅启用我的代码 有效地解决了这个问题。

那个复选框正是两种环境之间的区别。尝试在 "working" 机器上取消选中它并在那里遇到相同的异常,因此我可以确认此行为是稳定且一致的(现在我很高兴)。

所以问题只是调试器试图跟踪正在调试的代码并读取动态对象的成员,而这些成员是创建动态对象的程序集的内部成员。这就是它在调试器下失败的原因,这就是它在 运行 没有调试器的情况下工作的原因。