Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';t使用Newtonsoft.Json.Linq反序列化对象;_C#_Json.net - Fatal编程技术网

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可能不会比反序列化快。有关反序列化与直接解析的比较,请参阅。