C#中如何将嵌套JSON数组反序列化为ExpandoObject的数组?
解决Json.NET反序列化ExpandoObject时嵌套数组转为List导致Jint无法调用数组方法的问题
问题场景
- 无预定义强类型类,需反序列化带嵌套数组的JSON对象
- 使用
ExpandoObjectConverter反序列化为ExpandoObject时,嵌套数组会被转为List<T>,Jint引擎无法识别该类型,调用filter/map等JS数组方法失败 - 使用
JObject解析时,JArray同样不支持JS数组原生方法 - 仅定义强类型类并将嵌套结构声明为数组时,Jint才能正常执行预期逻辑
解决方案
核心思路是让Json.NET在反序列化嵌套数组时直接生成CLR数组而非List<T>,提供两种可行实现:
方案1:自定义ExpandoObjectConverter
继承默认的ExpandoObjectConverter,重写ReadJson方法,遇到数组时将元素转成数组返回:
using System.Collections.Generic; using System.Dynamic; using Newtonsoft.Json; using Newtonsoft.Json.Converters; public class ExpandoWithArraysConverter : ExpandoObjectConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // 处理数组节点:递归反序列化每个元素后转为数组 if (reader.TokenType == JsonToken.StartArray) { var elements = new List<object>(); while (reader.Read() && reader.TokenType != JsonToken.EndArray) { elements.Add(base.ReadJson(reader, typeof(ExpandoObject), null, serializer)); } return elements.ToArray(); } // 其他节点沿用默认逻辑 return base.ReadJson(reader, objectType, existingValue, serializer); } }
使用方式:
dynamic v = JsonConvert.DeserializeObject<ExpandoObject>(obj, new ExpandoWithArraysConverter());
方案2:JToken转动态对象(手动递归转换)
先将JSON解析为JObject,再递归遍历所有节点,把JArray转为CLR数组、JObject转为ExpandoObject:
using System.Dynamic; using Newtonsoft.Json.Linq; public static object ConvertJTokenToDynamic(JToken token) { return token.Type switch { JTokenType.Object => ConvertJObjectToExpando(token as JObject), JTokenType.Array => token.Select(ConvertJTokenToDynamic).ToArray(), _ => ((JValue)token).Value }; } private static ExpandoObject ConvertJObjectToExpando(JObject jObj) { var expando = new ExpandoObject(); var dict = (IDictionary<string, object>)expando; foreach (var prop in jObj.Properties()) { dict[prop.Name] = ConvertJTokenToDynamic(prop.Value); } return expando; }
使用方式:
var jObj = JObject.Parse(obj); dynamic v = ConvertJTokenToDynamic(jObj);
验证效果
使用原示例代码测试,两种方案都能让Jint正常执行eval函数,返回预期结果30(13+17)。
内容的提问来源于stack exchange,提问作者ZorgoZ
相关产品推荐
相关产品推荐

