将JSON转换为DataTable时遇Newtonsoft.Json序列化异常求助
解决JSON转DataTable的序列化异常
错误原因
Newtonsoft.Json将JSON转为DataTable时,要求最外层必须是数组格式([]包裹的结构),但你提供的JSON最外层是对象({}包裹),因此触发了Unexpected JSON token when reading DataTable. Expected StartArray, got StartObject错误。
解决方案
核心思路是先剥开外层的对象结构,提取出里面的目标数组,再将数组转为DataTable。以下是几种可行的实现方式:
方法1:固定键名直接提取
如果外层的键名(如"AAPL"、"390")是固定的,可通过动态对象直接获取数组:
var prettyJson = @"{""AAPL"": {""390"": [{""root"": ""AAPL"",""expiry"": ""2024-06-21T00:00:00""}]}}"; // 解析外层对象 dynamic jsonObj = JsonConvert.DeserializeObject(prettyJson); // 提取目标数组 JArray targetArray = jsonObj.AAPL["390"]; // 数组转DataTable DataTable dt = targetArray.ToObject<DataTable>();
方法2:强类型字典解析
需要严谨类型约束时,用嵌套字典解析外层结构:
var prettyJson = @"{""AAPL"": {""390"": [{""root"": ""AAPL"",""expiry"": ""2024-06-21T00:00:00""}]}}"; // 反序列化为嵌套字典 var outerDict = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, JArray>>>(prettyJson); // 获取目标数组 JArray targetArray = outerDict["AAPL"]["390"]; // 转DataTable DataTable dt = targetArray.ToObject<DataTable>();
方法3:动态遍历提取(键名不固定场景)
如果外层键名是动态变化的,可通过遍历JSON结构找到数组:
var prettyJson = @"{""AAPL"": {""390"": [{""root"": ""AAPL"",""expiry"": ""2024-06-21T00:00:00""}]}}"; JObject outerObj = JObject.Parse(prettyJson); JArray targetArray = null; // 遍历外层对象,找到嵌套的数组 foreach (var innerObj in outerObj.Values<JObject>()) { foreach (var arr in innerObj.Values<JArray>()) { targetArray = arr; break; } if (targetArray != null) break; } // 找到数组后转DataTable if (targetArray != null) { DataTable dt = targetArray.ToObject<DataTable>(); // 后续处理DataTable逻辑 }
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

