2025年C# dynamic中的JSON:无痛反序列化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JSON与C# dynamic:为何这仍是痛点(以及如何解决)

\n\n

你是否曾看着API返回的JSON,心想:“天哪,为什么你如此复杂?”尤其是当数据结构像圣彼得堡的天气一样变幻莫测时。经典例子是来自外部服务的响应,字段有时是字符串,有时是数组,有时甚至是null。或者当你需要快速解析JSON,但为其创建单独的类就像用显微镜来切割微芯片一样大材小用。

\n\n

正是针对这种情况,C#提供了dynamic的魔法。Stack Overflow上“Deserialize JSON into C# dynamic object?”的问题获得了数千次浏览——这绝非偶然。在2025年,当微服务和动态API成为常态时,快速灵活地处理JSON的能力是开发者的超能力。

\n\n

在本文中,我们将探讨在C#中将JSON反序列化为dynamic object的最佳实践。没有枯燥的理论,只有代码、示例和实用技巧。开始吧!

\n\n

为什么用dynamic?而不是直接用JObject?

\n\n

好问题。C#中有JObject(来自Newtonsoft.Json)和JsonDocument(来自System.Text.Json)。它们也能“即时”解析JSON。但dynamic提供了一个重要的东西——语法糖。

\n\n

比较一下:

\n\n
// 通过JObject\nvar json = JObject.Parse(rawJson);\nvar name = (string)json["user"]["name"];\n\n// 通过dynamic\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(rawJson);\nvar name = obj.user.name;\n
\n\n

第二种方式读起来像普通代码,而不是“获取键、转换类型、检查null”。这在处理深层嵌套的JSON时尤其方便。

\n\n

方法1:经典方案——Newtonsoft.Json (Json.NET)

\n\n

是的,现在已经是2025年,但Newtonsoft.Json仍然活跃且健康。许多遗留项目,甚至一些现代项目,仍在使用它。为什么?灵活性、可扩展性和海量配置选项。

\n\n

基本示例

\n\n
using Newtonsoft.Json;\n\nstring json = @"\n{\n    'name': '阿列克谢',\n    'age': 30,\n    'skills': ['C#', 'Python', 'SQL'],\n    'address': {\n        'city': '莫斯科',\n        'zip': 101000\n    }\n}";\n\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(json);\n\nConsole.WriteLine(obj.name);        // 阿列克谢\nConsole.WriteLine(obj.age);         // 30\nConsole.WriteLine(obj.skills[0]);   // C#\nConsole.WriteLine(obj.address.city); // 莫斯科\n
\n\n

一切简单而优雅。但有一个问题:使用dynamic时,你会失去IntelliSense和编译时的类型检查。字段名称的错误只会在运行时暴露。因此:

\n\n
    \n
  • 仅在你无法控制的数据读取中使用dynamic。
  • \n
  • 务必用try-catch包裹调用。
  • \n
  • 不要滥用——如果JSON结构稳定,最好创建DTO类。
  • \n
\n\n

方法2:现代方案——System.Text.Json

\n\n

从.NET Core 3.0开始,微软推广System.Text.Json——快速、原生、无外部依赖。到2025年,这已成为新项目的标准。

\n\n

但有一个陷阱:System.Text.Json默认不支持反序列化为dynamic。需要稍微变通一下。

\n\n

方案A:通过JsonDocument和ExpandoObject

\n\n
using System.Text.Json;\nusing System.Dynamic;\n\nstring json = @"{""name"":""叶莲娜"",""age"":25,""active"":true}";\n\nusing JsonDocument doc = JsonDocument.Parse(json);\ndynamic obj = ConvertToExpando(doc.RootElement);\n\nConsole.WriteLine(obj.name);   // 叶莲娜\nConsole.WriteLine(obj.age);    // 25\nConsole.WriteLine(obj.active); // True\n\nstatic ExpandoObject ConvertToExpando(JsonElement element)\n{\n    var expando = new ExpandoObject();\n    var dict = (IDictionary<string, object>)expando;\n\n    foreach (var property in element.Enumera                

博客

书籍推荐