C#:解析非JSON数组的api响应到具有x属性的类对象 [英] C#: Parsing a non-JSON array-only api response to a class object with x properties

查看:138
本文介绍了C#:解析非JSON数组的api响应到具有x属性的类对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到一些Rest API的响应,该响应仅返回一些数组,如下所示:

I have a response from some Rest API that just returns some array of arrays like the following:

[
[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 +.

In this example, the amount of datasets is 3, but the amount is always different and could be 100+ also.

我想将此内容读入一个类对象,该类对象根据响应中显示的每种值的类型具有12个数组:

I want to have this read out into a class object, which has 12 arrays according to each type of value shown in the response:

public class foo
{
    ...
    public int[] firstParam;
    public string[] secondParam;
    public string[] thirdParam;

    ...        
}

例如,firstParam应该包含{123,456,789}secondParam应该包含{"0.01","0.04","0.05"},依此类推.

For example, firstParam should contain then {123,456,789}; secondParam should contain {"0.01","0.04","0.05"} and so on.

用于币安的Public Rest API:Kline/烛台数据..例如,某些查询例如 https://api.binance .com/api/v1/klines?symbol = XVGBTC& interval = 1h

The schema for the columns is known and documented in Public Rest API for Binance: Kline/Candlestick data.. An example would be some query like https://api.binance.com/api/v1/klines?symbol=XVGBTC&interval=1h

推荐答案

API响应完全有效 JSON ;它是原始值的锯齿形二维数组,其中的列具有 json的问题进行解析和反序列化.网络,例如作为object [][]:

The API response is perfectly valid JSON; it is a jagged 2d array of primitive values where the columns have specific meanings as defined in the Public Rest API for Binance: Kline/Candlestick data. As such it can be parsed and deserialized using json.net, e.g. as an object [][]:

var arrays = JsonConvert.DeserializeObject<object [][]>(jsonString);

(示例工作 .Net小提琴#1 .)

但是,我建议您设计一个代表以下内容的类BinanceKlineData,而不是将JSON反序列化为锯齿状的2d对象数组或(如您在问题中所建议的那样)将单个根对象反序列化为具有与列值相对应的数组属性这些特定列的一行值,然后使用List<BinanceKlineData> >来自 C#JSON.NET的自定义JsonConverter ObjectToArrayConverter<BinanceKlineData> JSON.NET-反序列化使用异常数据结构的响应 .

However, rather than deserializing the JSON into a jagged 2d object array or (as you suggest in your question) a single root object with array properties corresponding to column values, I would recommend that you design a class BinanceKlineData that represents a single row of values for those specific columns, then deserialize into a List<BinanceKlineData> using the custom JsonConverter ObjectToArrayConverter<BinanceKlineData> from C# JSON.NET - Deserialize response that uses an unusual data structure.

首先,使用文档中各列的含义,您可以按以下方式定义类型BinanceKlineData:

Firstly, using the documented meanings of the columns, you can define your type BinanceKlineData as follows:

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如何通过列索引将列映射到属性.还请注意,尽管数字列在JSON中显示为字符串,但我仍将其建模为decimal.如果您更喜欢字面反序列化,则可以使用string.

Notice that I have annotated the properties with [JsonProperty(Order = N)]. This order corresponds to the order of the columns in the Rest API, and will be used to inform Json.NET how to map columns to properties by column index. Notice also that I modeled the numeric columns as decimal despite the fact that they appear as strings in the JSON. You could use string if you prefer a more literal deserialization.

接下来,从此答案中获取通用的ObjectToArrayConverter<T>.它具有利用Order = N元数据按列索引将行值映射到通用类型T的成员值的逻辑.

Next, grab the generic ObjectToArrayConverter<T> from this answer. It has logic to make use of the Order = N metadata to map row values to member values in the generic type T by column index.

最后,您将能够按List<BinanceKlineData>的顺序反序列化JSON,如下所示:

Finally, you will be able to deserialize the JSON as a List<BinanceKlineData> as follows:

var settings = new JsonSerializerSettings
{
    Converters = { new ObjectToArrayConverter<BinanceKlineData>() },
};

var root = JsonConvert.DeserializeObject<List<BinanceKlineData>>(jsonString, settings);

示例工作 .Net小提琴#2 .

或者,如果您愿意,可以按如下所示将转换器直接应用于BinanceKlineData:

Or if you prefer you could apply the converter directly to BinanceKlineData as follows:

[JsonConverter(typeof(ObjectToArrayConverter<BinanceKlineData>))]
public class BinanceKlineData
{
    // Remainder as before
}

将转换器直接应用于该类型时,不再需要通过JsonSerializerSettings.Converters将其传递.

When the converter is applied directly to the type it is no longer necessary to pass it in via JsonSerializerSettings.Converters.

示例小提琴#3 .

这篇关于C#:解析非JSON数组的api响应到具有x属性的类对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆