【问题标题】:RuntimeBinderException while using Newtonsoft Json with dynamic after installing Reactive Extensions安装 Reactive Extensions 后使用带有动态的 Newtonsoft Json 时出现 RuntimeBinderException
【发布时间】:2026-02-07 14:05:01
【问题描述】:

我使用的是以下代码:

public async Task<string> LoginAsync(string username, string password)
{
    //removed irrelevant code from snippet

    var response = await JSonConvert.DeSerializeObjectAsync<dynamic>(responseText);
    return (response.success == SUCCESS ? response.data.sid : String.Empty);
}

在我通过 NuGet 安装 Reactive Extensions 之前,这一直有效。
从该方法的最后一行开始,只需抛出一个RuntimeBinderException

{"'Newtonsoft.Json.Linq.JObject' 不包含对 '成功'"}

现在让它工作的唯一方法是使用这个:

return (response["success"].ToString() == SUCCESS ? response["data"]["sid"].ToString() : String.Empty);

我尝试了另一个 JSon 库 (JsonFX2.0),但也遇到了 RuntimeBinderException:

{"'ExpandoObject' 不包含对 '成功'"}

服务返回的json如下所示:

{
  "data": {
    "sid": "sK7gyGm1kfEUc"
  },
  "success": true
}

我尝试删除响应式扩展引用,但这没有帮助。

那么这里发生了什么?

更新

我在 VS2013 中创建了一个新项目,并从原始解决方案中复制了源代码。 这就是解决方案中的所有代码,因为它只是一个游乐场解决方案。

然后,我使用 NuGet 添加了 JSON.NET 库(如前所述),运行了解决方案,它按预期工作。然后我像以前一样通过 NuGet 添加了响应式扩展库,并且该解决方案仍然按预期工作。我在任何时候都没有更改源代码(因为在原始解决方案中我还没有在代码中使用响应式扩展)

所以我不知道在原始解决方案中是什么原因造成的(仍然不起作用)

更新 2

我在某个时候多次运行代码的工作版本 没有改变任何相同的 RuntimeBinderException 再次开始弹出。

我检查了服务器的响应,它和以前完全一样。 我说的不相关的代码:

public async Task<string> LoginAsync(string username, string password)
{
    var request = new Request(hostname, ApiName.SYNO_API_AUTH, 2, ApiPath.AUTHCGI, ApiMethod.LOGIN);
    request.AddParameter("account", username);
    request.AddParameter("passwd", password);
    request.AddParameter("format", "sid");

    var responseText = await client.DownloadStringTaskAsync(request.ToString());    
    var response = await JsonConvert.DeserializeObjectAsync<dynamic>(responseText);
    return response.success == TRUE ? response.data.sid : String.Empty;
}

这是第一个被调用的方法,现在最后一行再次抛出 RuntimeBinder 异常。而且我非常有信心,如果我要将所有内容复制到新的解决方案中,它就会再次起作用。 (我会做的)

更新 3

所以现在我找到了停止工作的解决方案。我把 Program.cs 的全部内容(因为这只是一个用于测试的控制台应用程序)复制到一个新的解决方案中。 通过nuget添加包引用并执行应用程序,它很简单。

因此,出于某种原因,Visual Studio 似乎正在做一些阻止它工作的事情。

更新 4

对于不起作用的解决方案。如果我从 Visual Studio 中调试解决方案 但是,如果我打开 bin/Debug 目录并执行,我会得到 RuntimeBinderException 程序直接运行就好了。如果我从 Visual Studio 中运行解决方案 没有调试它运行得很好。因此,启用调试器时我遇到了问题。我还发现了另一个类似问题的问题:RuntimeBinderException when parsing json with Newtonsoft.Json

【问题讨论】:

  • 你能把“不相关”的代码加回去吗?唯一合乎逻辑的解释是 responseText 不是您所期望的,或者您运行的是不同版本的 JSonConvert.DeSerializeObjectAsync
  • 这里建议的答案似乎是:*.com/questions/2954531/… 确实在一定程度上解决了问题,让我可以再次调试应用程序
  • 感谢所有更新!我今天遇到了同样的问题,本来运行良好的东西突然停止工作,需要新的语法。删除调试器解决了我的直接问题,稍后我将研究更永久的修复:)

标签: c# json system.reactive


【解决方案1】:

由于 Json.NET 或 Rx-Main 包在 BCL 之外没有任何相互依赖关系,因此很难将包安装视为问题的根源。这是一条红鲱鱼。绝对确定,检查 bin 输出中没有 Rx dll。

您的代码或其他内容发生了变化。您是否添加/删除了任何可能引入扩展方法问题的 using 语句?您确定代码根本没有改变吗?你确定服务响应是一样的吗? Json.NET 包版本有变化吗?

我的猜测是,您的服务在某些时候停止返回成功属性,而巧合的是,当您更改代码时又开始返回它。

【讨论】:

  • 我会验证所有这些并回复您。我还将获取源并将其发布到一个新项目中。该服务没有改变,因为它只是我 Synology NAS 的 API。
  • 创建了一个新的解决方案并复制了所有内容,就像魅力一样......(请参阅更新的问题)。这就像魔术......或者巫毒教
【解决方案2】:

我在 VS 2015 中遇到了这个确切的问题。

修复是在“工具”>“选项”>“调试”>“常规”中启用“仅我的代码”。

【讨论】:

  • 对我来说,我同意。在调试时抛出这个看起来像是一个致命的异常。果然,如果你只是按 F10 足够多,它就会通过它并最终工作。 “只是我的代码”将等效地工作,因为它隐藏了第 3 方代码中捕获的第一次机会异常。
最近更新 更多