C#如何反序列化含动态键的API返回字典列表?
动态键JSON反序列化解决方案
针对你遇到的每个对象包含动态时间戳键+固定index键的JSON反序列化问题,提供以下几种可行方案(以C#+Newtonsoft.Json为例,这是最常用的JSON处理库):
方案1:用JArray手动解析(最直观易调试)
直接将JSON加载为JArray,遍历每个对象提取所需数据:
using Newtonsoft.Json.Linq; // 假设responseJson是API返回的原始JSON字符串 JArray dataArray = JArray.Parse(responseJson); var parsedList = new List<DynamicDataModel>(); foreach (JObject item in dataArray) { // 提取固定的index字段 string index = item["index"].ToString(); // 筛选出动态时间戳字段(排除index) var timestampProp = item.Properties().First(p => p.Name != "index"); parsedList.Add(new DynamicDataModel { Index = index, Timestamp = timestampProp.Name, Value = timestampProp.Value.ToString() }); } // 自定义模型用于存储解析后的数据 public class DynamicDataModel { public string Index { get; set; } public string Timestamp { get; set; } public string Value { get; set; } }
方案2:自定义JsonConverter实现直接反序列化
如果希望直接反序列化为强类型列表,可编写自定义转换器:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class DynamicTimestampConverter : JsonConverter<List<DynamicDataModel>> { public override List<DynamicDataModel> ReadJson(JsonReader reader, Type objectType, List<DynamicDataModel> existingValue, bool hasExistingValue, JsonSerializer serializer) { var dataArray = JArray.Load(reader); var result = new List<DynamicDataModel>(); foreach (JObject obj in dataArray) { var model = new DynamicDataModel(); foreach (var prop in obj.Properties()) { if (prop.Name == "index") { model.Index = prop.Value.ToString(); } else { model.Timestamp = prop.Name; model.Value = prop.Value.ToString(); } } result.Add(model); } return result; } public override void WriteJson(JsonWriter writer, List<DynamicDataModel> value, JsonSerializer serializer) { // 若不需要序列化回JSON,可直接抛出异常或留空 throw new NotImplementedException(); } public override bool CanWrite => false; } // 使用转换器进行反序列化 var jsonSettings = new JsonSerializerSettings(); jsonSettings.Converters.Add(new DynamicTimestampConverter()); var parsedData = JsonConvert.DeserializeObject<List<DynamicDataModel>>(responseJson, jsonSettings);
方案3:修复Dictionary<string, string>反序列化问题
你之前用List<Dictionary<string, string>>报错,大概率是因为JSON中动态键对应的值不是字符串类型(比如数字),改用List<Dictionary<string, object>>即可兼容:
using Newtonsoft.Json; var rawDictList = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(responseJson); var parsedList = new List<DynamicDataModel>(); foreach (var dict in rawDictList) { var model = new DynamicDataModel(); foreach (var kvp in dict) { if (kvp.Key == "index") { model.Index = kvp.Value.ToString(); } else { model.Timestamp = kvp.Key; model.Value = kvp.Value.ToString(); } } parsedList.Add(model); }
补充说明
- 若使用.NET Core 3.0+内置的
System.Text.Json,逻辑类似:用JsonDocument解析JSON,遍历元素提取数据,或编写对应的JsonConverter。 - 确保已通过NuGet安装
Newtonsoft.Json包(若用方案1/2/3)。
内容的提问来源于stack exchange,提问作者FX_Sektor
相关产品推荐
相关产品推荐

