首页 > 解决方案 > 从 JSON 反序列化混合类型的无名数组

问题描述

我正在尝试为此 WEB-API 方法编写 C# 类型和反序列化代码,使用 C# 的 Newtonsoft JSON 库:https ://docs.kraken.com/rest/#operation/getTickerInformation

示例 JSON 如下所示:

{
  "error": [],
  "result": {
    "XXBTZUSD": {
      "a": [
        "52609.60000",
        "1",
        "1.000"
      ],
      "b": [
        "52609.50000",
        "1",
        "1.000"
      ],
      "c": [
        "52641.10000",
        "0.00080000"
      ],
      "v": [
        "1920.83610601",
        "7954.00219674"
      ],
      "p": [
        "52389.94668",
        "54022.90683"
      ],
      "t": [
        23329,
        80463
      ],
      "l": [
        "51513.90000",
        "51513.90000"
      ],
      "h": [
        "53219.90000",
        "57200.00000"
      ],
      "o": "52280.40000"
    }
  }
}

对于其他 API 方法,我使用如下代码直接映射到我的类型:

public static Ticker GetTicker(string pair)
{
    try
    {
        return Deserialize<Ticker>GetJObject($"https://api.kraken.com/0/public/Ticker?pair={pair}");
        
    }
    catch
    {
        throw;
    }
}

private static T Deserialize<T>(JObject jObject)
{
    try
    {
        var err = jObject["error"];
        if (err.HasValues)
        {
            throw new Exception("Kraken Error" + String.Join(',',err.ToObject<string[]>()));
        }
        return jObject["result"].ToObject<T>();
    }
    catch
    {
        throw;
    }
}

但在这种情况下,JSON 在任意数组中返回无名值 - 并且还Ticker嵌套在另一个名为pair. 更糟糕的是,数组使用混合类型。所以我正在诉诸(到目前为止)这样的事情:

    public class Ticker
    {
        [JsonProperty("a")]
        public float[] ask { get; set; }
        [JsonProperty("b")]
        public float[] bid { get; set; }
        [JsonProperty("c")]
        public float[] close { get; set; }
        [JsonProperty("v")]
        public float[] volume { get; set; }
        [JsonProperty("p")]
        public float[] volumeWeightedPrice { get; set; }
        [JsonProperty("t")]
        public int[] trades { get; set; }
        [JsonProperty("l")]
        public float[] low { get; set; }
        [JsonProperty("h")]
        public float[] high { get; set; }
        [JsonProperty("o")]
        public float opening { get; set; }
    }
}

我是 NewtonSoft 的 JSON 库的新手,想知道我是否可以让它纯粹在Ticker类声明上工作,大概是使用注释?或者,如果我必须深入研究自定义反序列化代码......那会是什么样子?

标签: c#jsonjson.net

解决方案


模型:

public class Ticker
{
    [JsonProperty("a")]
    public float[] ask { get; set; }
    [JsonProperty("b")]
    public float[] bid { get; set; }
    [JsonProperty("c")]
    public float[] close { get; set; }
    [JsonProperty("v")]
    public float[] volume { get; set; }
    [JsonProperty("p")]
    public float[] volumeWeightedPrice { get; set; }
    [JsonProperty("t")]
    public int[] trades { get; set; }
    [JsonProperty("l")]
    public float[] low { get; set; }
    [JsonProperty("h")]
    public float[] high { get; set; }
    [JsonProperty("o")]
    public float opening { get; set; }
}

public class Result
{
    [JsonProperty("XXBTZUSD")]
    public Ticker Ticker { get; set; }
}

public class Root
{
    public List<object> error { get; set; }
    public Result result { get; set; }
}

反序列化:

Root r = JsonConvert.DeserializeObject<Root>(json_text);
Ticker ticker = r.result.Ticker;

使用权:
ticker.ask[0] //52609,6


推荐阅读