我得到了一些Rest API的响应,它只返回一些数组,如下所示:
[
[123,"0.01","0.02","0.03","0.04","12345.00000",123456789,"300.000",4000,"123.000","456.000","0"],
[456,"0.04","0.03","0.02","0.01","54321.00000",987654321,"500.000",4000,"123.000","456.000","1"],
[789,"0.05","0.06","0.07","0.08","12345.00000",123456789,"700.000",8000,"456.000","123.000","0"]
]
在此示例中,数据集的数量为3,但数量总是不同的,也可能是100+。
我希望将其读入一个类对象,该对象根据响应中显示的每种类型的值有12个数组:
public class foo
{
...
public int[] firstParam;
public string[] secondParam;
public string[] thirdParam;
...
}
例如,firstParam
应包含{123,456,789}
; secondParam
应包含{"0.01","0.04","0.05"}
等等。
列的架构已知并记录在Public Rest API for Binance: Kline/Candlestick data.中。一个例子是https://api.binance.com/api/v1/klines?symbol=XVGBTC&interval=1h
之类的查询答案 0 :(得分:1)
API响应完全有效JSON;它是一个锯齿状的2d原始值数组,其中列具有Public Rest API for Binance: Kline/Candlestick data中定义的特定含义。因此,可以使用json.net对其进行解析和反序列化,例如作为object [][]
:
var arrays = JsonConvert.DeserializeObject<object [][]>(jsonString);
(示例工作.Net fiddle #1。)
但是,我不建议将JSON反序列化为锯齿状的2d对象数组,或者(如您在问题中所建议的)具有与列值对应的数组属性的单个根对象,我建议您设计一个类BinanceKlineData
表示这些特定列的单行值,然后使用custom JsonConverter
中的C# JSON.NET - Deserialize response that uses an unusual data structure List<BinanceKlineData>
反序列化为ObjectToArrayConverter<BinanceKlineData>
。
首先,使用列中记录的含义,您可以按如下方式定义类型BinanceKlineData
:
public class BinanceKlineData
{
[JsonProperty(Order = 1)]
public long OpenTime { get; set; }
[JsonProperty(Order = 2)]
public decimal Open { get; set; } // Or string, if you prefer
[JsonProperty(Order = 3)]
public decimal High { get; set; } // Or string, if you prefer
[JsonProperty(Order = 4)]
public decimal Low { get; set; } // Or string, if you prefer
[JsonProperty(Order = 5)]
public decimal Close { get; set; } // Or string, if you prefer
[JsonProperty(Order = 6)]
public decimal Volume { get; set; } // Or string, if you prefer
[JsonProperty(Order = 7)]
public long CloseTime { get; set; }
[JsonProperty(Order = 8)]
public decimal QuoteAssetVolume { get; set; } // Or string, if you prefer
[JsonProperty(Order = 9)]
public long NumberOfTrades { get; set; } // Should this be an long or a decimal?
[JsonProperty(Order = 10)]
public decimal TakerBuyBaseAssetVolume { get; set; }
[JsonProperty(Order = 11)]
public decimal TakerBuyQuoteAssetVolume { get; set; }
// public string Ignore { get; set; }
}
请注意,我已使用[JsonProperty(Order = N)]
注释了属性。此顺序对应于Rest API中列的顺序,并将用于通知Json.NET如何按列索引将列映射到属性。另请注意,我将数字列建模为decimal
,尽管它们在JSON中显示为字符串。如果您更喜欢更直接的反序列化,可以使用string
。
接下来,从this answer抓取通用ObjectToArrayConverter<T>
。它具有使用Order = N
元数据通过列索引将行值映射到泛型类型T
中的成员值的逻辑。
最后,您将能够将JSON反序列化为List<BinanceKlineData>
,如下所示:
var settings = new JsonSerializerSettings
{
Converters = { new ObjectToArrayConverter<BinanceKlineData>() },
};
var root = JsonConvert.DeserializeObject<List<BinanceKlineData>>(jsonString, settings);
示例工作.Net fiddle #2。
或者,如果您愿意,可以将转换器直接应用于BinanceKlineData
,如下所示:
[JsonConverter(typeof(ObjectToArrayConverter<BinanceKlineData>))]
public class BinanceKlineData
{
// Remainder as before
}
当转换器直接应用于该类型时,不再需要通过JsonSerializerSettings.Converters
传递它。
示例fiddle #3。
答案 1 :(得分:0)
根据确切的响应格式,您可以执行以下操作:
var s = "[[123,\"0.01\",\"0.02\",\"0.03\",\"0.04\",\"12345.00000\",123456789,\"300.000\",4000,\"123.000\",\"456.000\",\"0\"],[456,\"0.04\",\"0.03\",\"0.02\",\"0.01\",\"54321.00000\",987654321,\"500.000\",4000,\"123.000\",\"456.000\",\"1\"],[789,\"0.05\",\"0.06\",\"0.07\",\"0.08\",\"12345.00000\",123456789,\"700.000\",8000,\"456.000\",\"123.000\",\"0\"]]";
var lines = s.Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries).Select(a => a.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(b => b.TrimEnd('"').TrimStart('"')).ToArray()).Where(a => a.Any());
var c = lines.Count();
var foo = new foo
{
firstParam = new int[c],
secondParam = new string[c],
thirdParam = new string[c]
};
for (int i = 0; i < c; i++)
{
foo.firstParam[i] = Int32.Parse(lines.ElementAt(i)[0]);
foo.secondParam[i] = lines.ElementAt(i)[1];
foo.thirdParam[i] = lines.ElementAt(i)[2];
}
Console.WriteLine(string.Join(", ", foo.firstParam)); \\123, 456, 789
Console.WriteLine(string.Join(", ", foo.secondParam)); \\0.01, 0.04, 0.05
Console.WriteLine(string.Join(", ", foo.thirdParam)); \\0.02, 0.03, 0.06