【问题标题】:Parsing dynamic JSON array in C# using Newtonsoft使用 Newtonsoft 在 C# 中解析动态 JSON 数组
【发布时间】:2018-03-10 14:58:42
【问题描述】:

我的市场 API 服务停止了我用来将数据抓取到 C# 应用程序中的调用。此后,他们发布了“批量报价”功能,实际上可以在我的应用程序中节省大量工作。它以 JSON 格式返回数据。我正在使用 Newtonsoft 解析我的旧 API 调用,它返回一个非常可预测的输出。但是,现在批量报价 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"
        }
    ]
}

所以“股票行情”数组是我每次都需要抓取的,数组中元素的数量取决于用户的输入。

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

dynamic obj = JsonConvert.DeserializeObject(rawJSON);

这似乎创建了一些具有 2 个孩子的通用对象。我需要第二个孩子的所有孩子,“股票行情”。该对象包含一个 count 方法,该方法显示“Stock Quotes”有多少子元素。我只是不确定获取每个子元素需要使用的语法。目标是将每个子元素放入自定义类的对象字典中。

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

注意:所有其他方法都失败了我可能会为包含“Stock Quotes”子项的方括号处理字符串,然后解析它们,等等。又快又脏,它可能会奏效——但一定有更优雅的方法,对吧?

【问题讨论】:

  • 不要使用dynamic,只要解析成JObject,就可以直接按名称访问属性,按索引访问数组

标签: c# json json.net json-deserialization


【解决方案1】:

您可以通过为每个集合创建类并使用 [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);

【讨论】:

  • 谢谢,昨晚我能够使用我现有的动态对象来实现这个解决方案,然后通过我的动态运行一个 foreach 将每个 StockQuote 放入 , StockQuote.price>。我回家后会发布代码。感谢您的帮助!
  • @Marcos :如果我的传入数据非常嵌套并且嵌套级别不统一,您的解决方案是否有用。
  • 这实际上取决于您的数据的具体情况,但通常如果有预定义且可预测的结构,即使深度嵌套,它也会起作用。如果无法预测,您可能需要为您的数据编写自定义解析器。
【解决方案2】:

您可以将 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"
  }
]}

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多