如何用System.Text.Json实现无类型JSON反序列化(替代Newtonsoft.Json)
使用System.Text.Json替代Newtonsoft.Json的dynamic反序列化方案
针对你需要处理未知结构JSON数组、并为每个元素添加额外属性的场景,System.Text.Json没有像Newtonsoft.Json那样直接返回dynamic的便捷实现,但可以通过以下几种方式达到等效效果:
方案一:使用ExpandoObject(最接近dynamic用法)
ExpandoObject支持动态添加属性,和你之前用dynamic的体验最接近,代码改写如下:
using System.Dynamic; using System.Text.Json; using System.Text.Json.Serialization; var strInput = @"[ { ""email"": ""hello@toto.com"", ""event"": ""processed"" }, { ""email"": ""hello@toto.com"", ""event"": ""deferred"", ""category"": ""cat facts"" }]"; // 反序列化为ExpandoObject列表 var rawData = JsonSerializer.Deserialize<List<ExpandoObject>>(strInput, new JsonSerializerOptions { PropertyNameCaseInsensitive = true, // 忽略大小写匹配属性 Converters = { new JsonStringEnumConverter() } // 处理枚举类型(如果有) }); List<dynamic> outputList = new List<dynamic>(); foreach (var item in rawData) { // 动态添加id属性 item.TryAdd("id", Guid.NewGuid().ToString()); outputList.Add(item); }
方案二:.NET 6+使用JsonNode(更灵活的JSON操作)
从.NET 6开始,System.Text.Json提供了JsonNode系列类型(JsonArray、JsonObject),支持直接修改JSON结构,代码示例:
using System.Text.Json.Nodes; var strInput = @"[ { ""email"": ""hello@toto.com"", ""event"": ""processed"" }, { ""email"": ""hello@toto.com"", ""event"": ""deferred"", ""category"": ""cat facts"" }]"; // 解析为JsonArray JsonArray rawData = JsonNode.Parse(strInput) as JsonArray; List<dynamic> outputList = new List<dynamic>(); foreach (JsonObject item in rawData) { // 直接添加id属性 item["id"] = Guid.NewGuid().ToString(); outputList.Add(item.AsValue()); }
注意事项
- System.Text.Json默认返回的
JsonElement是只读结构,无法直接添加属性,所以必须转换成ExpandoObject或JsonNode这类可修改的类型。 - 如果不需要修改JSON结构,只是读取数据,可以直接反序列化为
JsonElement:JsonElement data = JsonSerializer.Deserialize<JsonElement>(strJsonInput);
内容的提问来源于stack exchange,提问作者Benjamin Talmard
相关产品推荐
相关产品推荐

