C# Can';t使用Newtonsoft.Json.Linq反序列化对象;
我收到以下格式的字符串:C# Can';t使用Newtonsoft.Json.Linq反序列化对象;,c#,json.net,C#,Json.net,我收到以下格式的字符串: { "ok": true, "quote": { // the below is the same as returned through the REST quote API "symbol": "FAC", "venue": "OGEX", "bid": 5100, // best price currently bid for the stock "ask": 5125, // best price currently
{
"ok": true,
"quote": { // the below is the same as returned through the REST quote API
"symbol": "FAC",
"venue": "OGEX",
"bid": 5100, // best price currently bid for the stock
"ask": 5125, // best price currently offered for the stock
"bidSize": 392, // aggregate size of all orders at the best bid
"askSize": 711, // aggregate size of all orders at the best ask
"bidDepth": 2748, // aggregate size of *all bids*
"askDepth": 2237, // aggregate size of *all asks*
"last": 5125, // price of last trade
"lastSize": 52, // quantity of last trade
"lastTrade": "2015-07-13T05:38:17.33640392Z", // timestamp of last trade,
"quoteTime": "2015-07-13T05:38:17.33640392Z" // server ts of quote generation
}
}
出于性能原因,我想使用Newtonsoft.Json.Linq方式进行反序列化。当我尝试使用以下方法将Json字符串转换为Quote对象时:
public static Quote QuoteFromJson(string quoteJson)
{
var json = JObject.Parse(quoteJson);
var quote = json["quote"].
Select(q => new Quote
{
Ask = int.Parse(q["ask"].ToString()),
AskDepth = int.Parse(q["askDepth"].ToString()),
AskSize = int.Parse(q["askSize"].ToString()),
Bid = int.Parse(q["bid"].ToString()),
BidDepth = int.Parse(q["bidDepth"].ToString()),
BidSize = int.Parse(q["bidSize"].ToString()),
Last = int.Parse(q["last"].ToString()),
LastSize = int.Parse(q["lastSize"].ToString()),
LastTrade = q["lastTrade"].ToString(),
QuoteTime = q["quoteTime"].ToString(),
Symbol = q["symbol"].ToString(),
}).First();
return quote;
}
这将显示一条错误消息:
Cannot access child value on Newtonsoft.Json.Linq.JProperty
我做错了什么?以下是对你问题的直接回答:
quote
变量对应于JSON中的quote
标记。这是单个项目而不是集合,因此不应将其视为集合并使用Select
方法
相反,请直接访问它,如下所示:
var json = JObject.Parse(quoteJson);
var quote = json["quote"];
var result = new Quote
{
Ask = int.Parse(quote["ask"].ToString()),
AskDepth = int.Parse(quote["askDepth"].ToString()),
AskSize = int.Parse(quote["askSize"].ToString()),
Bid = int.Parse(quote["bid"].ToString()),
BidDepth = int.Parse(quote["bidDepth"].ToString()),
BidSize = int.Parse(quote["bidSize"].ToString()),
Last = int.Parse(quote["last"].ToString()),
LastSize = int.Parse(quote["lastSize"].ToString()),
LastTrade = quote["lastTrade"].ToString(),
QuoteTime = quote["quoteTime"].ToString(),
Symbol = quote["symbol"].ToString(),
};
您的问题是,您正在使用
选择
遍历“quote”
的子项,然后按名称检索它们的属性。如果“quote”
是一个数组,这将是合适的,但它不是--它已经是一个单一对象了。因此,你应该:
var rootObj = JObject.Parse(quoteJson);
var quoteObj = rootObj["quote"];
var quote = new Quote
{
Ask = (int)quoteObj["ask"],
AskDepth = (int)quoteObj["askDepth"],
AskSize = (int)quoteObj["askSize"],
Bid = (int)quoteObj["bid"],
BidDepth = (int)quoteObj["bidDepth"],
BidSize = (int)quoteObj["bidSize"],
Last = (int)quoteObj["last"],
LastSize = (int)quoteObj["lastSize"],
LastTrade = (string)quoteObj["lastTrade"],
QuoteTime = (string)quoteObj["quoteTime"],
Symbol = (string)quoteObj["symbol"],
};
注意,我正在使用。这将以与一致的方式处理数字国际化int.Parse()
但是,使用反序列化要简单得多:
var rootObj = JObject.Parse(quoteJson);
var quoteObj = rootObj["quote"];
var quote = quoteObj.ToObject<Quote>();
var rootObj=JObject.Parse(quoteJson);
var quoteObj=rootObj[“quote”];
var quote=quoteObj.ToObject();
我建议您对此进行计时,以确保它确实比linqtojson慢。为什么不直接将其解析为引号
?像这样:JsonConvert.DeserializeObject(quoteJson)
这会让生活变得简单,但DeserializeObject使用反射,这会大大降低我的应用程序的速度。比逐个属性使用JObject属性来构造对象慢吗?如果Json.NET对你来说不够快,我建议您在使用当前方法之前先查看其他库。这太乱了。我还建议您根据业务需求设定绩效目标,而不仅仅是通过查看剖析器“哦,伙计,我花了这么多时间反序列化”。很有可能您实际花费在网络IO上的时间要比反序列化的时间多得多。Linq到JSON可能不会比反序列化快。有关反序列化与直接解析的比较,请参阅。