使用 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);
我的市场 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")]
使用 类 而不是 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);