如何在C#中将无键JSON数组转换为自定义类对象?
解析无键JSON数组为C#类对象
你的JSON是嵌套数组结构,每个子数组对应一组结构化数据(看起来是加密货币K线数据),可以通过以下几种方式将其转换为C#类对象:
1. 先定义目标类
首先根据子数组的字段索引,创建对应的C#类(字段含义参考常见K线数据规范):
public class KlineData { public long OpenTime { get; set; } // 索引0:开盘时间戳 public decimal OpenPrice { get; set; } // 索引1:开盘价 public decimal HighPrice { get; set; } // 索引2:最高价 public decimal LowPrice { get; set; } // 索引3:最低价 public decimal ClosePrice { get; set; } // 索引4:收盘价 public decimal Volume { get; set; } // 索引5:成交量 public long CloseTime { get; set; } // 索引6:收盘时间戳 public decimal QuoteVolume { get; set; } // 索引7:成交额 public int TradeCount { get; set; } // 索引8:成交笔数 public decimal TakerBuyVolume { get; set; } // 索引9:主动买入成交量 public decimal TakerBuyQuoteVolume { get; set; } // 索引10:主动买入成交额 public string Ignore { get; set; } // 索引11:预留字段 }
2. 方法一:手动映射二维数组(简单快速)
先将JSON反序列化为二维数组,再手动将每个元素映射到类属性:
使用Newtonsoft.Json
using Newtonsoft.Json; var json = "[[1617235200000,\"58739.46000000\",\"59490.00000000\",\"57935.45000000\",\"58720.44000000\",\"47415.61722000\",1617321599999,\"2789238879.94337348\",1594431,\"22966.25673600\",\"1351151697.89222195\",\"0\"]]"; // 反序列化为二维数组 var rawArrays = JsonConvert.DeserializeObject<object[][]>(json); // 映射为KlineData列表 var klineList = rawArrays.Select(arr => new KlineData { OpenTime = (long)arr[0], OpenPrice = decimal.Parse((string)arr[1]), HighPrice = decimal.Parse((string)arr[2]), LowPrice = decimal.Parse((string)arr[3]), ClosePrice = decimal.Parse((string)arr[4]), Volume = decimal.Parse((string)arr[5]), CloseTime = (long)arr[6], QuoteVolume = decimal.Parse((string)arr[7]), TradeCount = (int)(long)arr[8], // 注意JSON中是长整型,转int需确保值在int范围内 TakerBuyVolume = decimal.Parse((string)arr[9]), TakerBuyQuoteVolume = decimal.Parse((string)arr[10]), Ignore = (string)arr[11] }).ToList();
使用System.Text.Json
using System.Text.Json; var json = "[[1617235200000,\"58739.46000000\",\"59490.00000000\",\"57935.45000000\",\"58720.44000000\",\"47415.61722000\",1617321599999,\"2789238879.94337348\",1594431,\"22966.25673600\",\"1351151697.89222195\",\"0\"]]"; // 反序列化为二维数组 var rawArrays = JsonSerializer.Deserialize<JsonElement[][]>(json); // 映射为KlineData列表 var klineList = rawArrays.Select(arr => new KlineData { OpenTime = arr[0].GetInt64(), OpenPrice = decimal.Parse(arr[1].GetString()), HighPrice = decimal.Parse(arr[2].GetString()), LowPrice = decimal.Parse(arr[3].GetString()), ClosePrice = decimal.Parse(arr[4].GetString()), Volume = decimal.Parse(arr[5].GetString()), CloseTime = arr[6].GetInt64(), QuoteVolume = decimal.Parse(arr[7].GetString()), TradeCount = arr[8].GetInt32(), TakerBuyVolume = decimal.Parse(arr[9].GetString()), TakerBuyQuoteVolume = decimal.Parse(arr[10].GetString()), Ignore = arr[11].GetString() }).ToList();
3. 方法二:自定义JSON转换器(可复用)
如果需要频繁处理这类JSON,可以自定义转换器,让序列化/反序列化过程更自动化:
使用Newtonsoft.Json自定义转换器
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class KlineDataConverter : JsonConverter<KlineData> { public override KlineData ReadJson(JsonReader reader, Type objectType, KlineData existingValue, bool hasExistingValue, JsonSerializer serializer) { var array = JArray.Load(reader); return new KlineData { OpenTime = array[0].Value<long>(), OpenPrice = array[1].Value<decimal>(), HighPrice = array[2].Value<decimal>(), LowPrice = array[3].Value<decimal>(), ClosePrice = array[4].Value<decimal>(), Volume = array[5].Value<decimal>(), CloseTime = array[6].Value<long>(), QuoteVolume = array[7].Value<decimal>(), TradeCount = array[8].Value<int>(), TakerBuyVolume = array[9].Value<decimal>(), TakerBuyQuoteVolume = array[10].Value<decimal>(), Ignore = array[11].Value<string>() }; } public override void WriteJson(JsonWriter writer, KlineData value, JsonSerializer serializer) { var array = new JArray { value.OpenTime, value.OpenPrice.ToString("F8"), value.HighPrice.ToString("F8"), value.LowPrice.ToString("F8"), value.ClosePrice.ToString("F8"), value.Volume.ToString("F8"), value.CloseTime, value.QuoteVolume.ToString("F8"), value.TradeCount, value.TakerBuyVolume.ToString("F8"), value.TakerBuyQuoteVolume.ToString("F8"), value.Ignore }; array.WriteTo(writer); } } // 使用转换器 var json = "[[1617235200000,\"58739.46000000\",\"59490.00000000\",\"57935.45000000\",\"58720.44000000\",\"47415.61722000\",1617321599999,\"2789238879.94337348\",1594431,\"22966.25673600\",\"1351151697.89222195\",\"0\"]]"; var settings = new JsonSerializerSettings(); settings.Converters.Add(new KlineDataConverter()); var klineList = JsonConvert.DeserializeObject<List<KlineData>>(json, settings);
使用System.Text.Json自定义转换器
using System.Text.Json; using System.Text.Json.Serialization; public class KlineDataSystemTextConverter : JsonConverter<KlineData> { public override KlineData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("JSON格式错误,预期数组起始符"); reader.Read(); var kline = new KlineData(); kline.OpenTime = reader.GetInt64(); reader.Read(); kline.OpenPrice = decimal.Parse(reader.GetString()); reader.Read(); kline.HighPrice = decimal.Parse(reader.GetString()); reader.Read(); kline.LowPrice = decimal.Parse(reader.GetString()); reader.Read(); kline.ClosePrice = decimal.Parse(reader.GetString()); reader.Read(); kline.Volume = decimal.Parse(reader.GetString()); reader.Read(); kline.CloseTime = reader.GetInt64(); reader.Read(); kline.QuoteVolume = decimal.Parse(reader.GetString()); reader.Read(); kline.TradeCount = reader.GetInt32(); reader.Read(); kline.TakerBuyVolume = decimal.Parse(reader.GetString()); reader.Read(); kline.TakerBuyQuoteVolume = decimal.Parse(reader.GetString()); reader.Read(); kline.Ignore = reader.GetString(); reader.Read(); if (reader.TokenType != JsonTokenType.EndArray) throw new JsonException("JSON格式错误,预期数组结束符"); return kline; } public override void Write(Utf8JsonWriter writer, KlineData value, JsonSerializerOptions options) { writer.WriteStartArray(); writer.WriteNumberValue(value.OpenTime); writer.WriteStringValue(value.OpenPrice.ToString("F8")); writer.WriteStringValue(value.HighPrice.ToString("F8")); writer.WriteStringValue(value.LowPrice.ToString("F8")); writer.WriteStringValue(value.ClosePrice.ToString("F8")); writer.WriteStringValue(value.Volume.ToString("F8")); writer.WriteNumberValue(value.CloseTime); writer.WriteStringValue(value.QuoteVolume.ToString("F8")); writer.WriteNumberValue(value.TradeCount); writer.WriteStringValue(value.TakerBuyVolume.ToString("F8")); writer.WriteStringValue(value.TakerBuyQuoteVolume.ToString("F8")); writer.WriteStringValue(value.Ignore); writer.WriteEndArray(); } } // 使用转换器 var json = "[[1617235200000,\"58739.46000000\",\"59490.00000000\",\"57935.45000000\",\"58720.44000000\",\"47415.61722000\",1617321599999,\"2789238879.94337348\",1594431,\"22966.25673600\",\"1351151697.89222195\",\"0\"]]"; var options = new JsonSerializerOptions(); options.Converters.Add(new KlineDataSystemTextConverter()); var klineList = JsonSerializer.Deserialize<List<KlineData>>(json, options);
内容的提问来源于stack exchange,提问作者The Undefined Coder
相关产品推荐
相关产品推荐

