使用 Newtonsoft 在 C# 中解析动态 JSON 数组

Parsing dynamic JSON array in C# using Newtonsoft

我的市场 API 服务中断了我用来将数据抓取到我的 C# 应用程序中的调用。他们已经发布了一个 "batch quote" 功能,实际上可以在我的应用程序中节省大量工作。它 returns JSON 中的数据。我正在使用 Newtonsoft 解析我的旧 API 调用,returns 一个非常可预测的输出。但是,现在批量报价 API 一次返回动态数量的股票,我无法完全破解语法。

JSON 输出:

{
    "Meta Data": {
        "1. Information": "Batch Stock Market Quotes",
        "2. Notes": "IEX Real-Time Price provided for free by IEX (https://iextrading.com/developer/).",
        "3. Time Zone": "US/Eastern"
    },
    "Stock Quotes": [
        {
            "1. symbol": "MSFT",
            "2. price": "96.1800",
            "3. volume": "20087326",
            "4. timestamp": "2018-03-09 13:53:07"
        },
        {
            "1. symbol": "AMD",
            "2. price": "11.6800",
            "3. volume": "63025764",
            "4. timestamp": "2018-03-09 13:53:08"
        },
        {
            "1. symbol": "NVDA",
            "2. price": "243.9600",
            "3. volume": "8649187",
            "4. timestamp": "2018-03-09 13:52:51"
        }
    ]
}

所以"Stock Quotes"数组是我每次都需要抓取的,数组中元素的数量取决于用户输入。

到目前为止我已经尝试过:

dynamic obj = JsonConvert.DeserializeObject(rawJSON);

这似乎用 2 children 创建了一些通用的 object。我需要第二个child、"Stock Quotes"的全部children。 object 包含一个计数方法,显示 "Stock Quotes" 有多少 child 个元素。我只是不确定我需要用来获取每个 child 元素的语法。目标是将每个 child 元素放入自定义 class 的 object 字典中。

非常感谢任何帮助,谢谢!

注意:所有其他方法都失败了我可能会处理包含 "Stock Quotes" children 的方括号的字符串,然后解析这些字符串,依此类推。快速而肮脏,它可能会起作用 - 但必须有更优雅的方法,对吗?

您可以将 JObject 变成 属性 名称和值的字典。

//parse JSON and grab it's children. 
var JSONobj = JObject.Parse(test).Children();

//use linq to turn into dictionary, array, or whatever suits your needs. 
//turn into dictionary of property name and value
var dictionary = JSONobj
     .Select(s => (s as JProperty))
     .ToDictionary(u => u.Name, v => v.Value);

//access the children of Stock Qoutes
var accessDictionaryChildren = dictionary["Stock Quotes"].Children();

var listChildren = accessDictionaryChildren.Children().ToList();

顺便说一句:

var dictionary["Stock Quotes"]="{[
  {
    "1. symbol": "MSFT",
    "2. price": "96.1800",
    "3. volume": "20087326",
    "4. timestamp": "2018-03-09 13:53:07"
  },
  {
    "1. symbol": "AMD",
    "2. price": "11.6800",
    "3. volume": "63025764",
    "4. timestamp": "2018-03-09 13:53:08"
  },
  {
    "1. symbol": "NVDA",
    "2. price": "243.9600",
    "3. volume": "8649187",
    "4. timestamp": "2018-03-09 13:52:51"
  }
]}

您可以通过为每个集合创建 类 并使用 [JsonProperty(PropertyName = "Field name")]

指定 JSON 数据中的字段名称来完成此操作

使用 类 而不是 dynamic 的一个优点是您可以获得 Intellisense。

因此,您的 DTO 类 可能如下所示:

public class Data
{
    [JsonProperty(PropertyName = "Meta Data")]
    public Metadata Metadata { get; set; }
    [JsonProperty(PropertyName = "Stock Quotes")]
    public IList<StockQuote> StockQuotes { get; set; }
}

public class Metadata
{
    [JsonProperty(PropertyName = "1. Information")]
    public string Information { get; set; }
    [JsonProperty(PropertyName = "2. Notes")]
    public string Notes { get; set; }
    [JsonProperty(PropertyName = "3. Time Zone")]
    public string Timezone { get; set; }
}

public class StockQuote
{
    [JsonProperty(PropertyName = "1. symbol")]
    public string Symbol { get; set; }
    [JsonProperty(PropertyName = "2. price")]
    public string Price { get; set; }
    [JsonProperty(PropertyName = "3. volume")]
    public string Volume { get; set; }
    [JsonProperty(PropertyName = "4. timestamp")]
    public string Timestamp { get; set; }
}

那么你只需:

var data = JsonConvert.DeserializeObject<Data>(str);