c# - 使用 Newtonsoft 解析 json 字符串会引发 Null 引用执行

标签 c# json json.net

我正在尝试解析这个 json 字符串

{ 
   "layers":[ 
      { 
         "metadata":{ 
            "cells":2, "records":42887000, "dataset":"uk_da", "query":"155ms", "sample":10, "calibrate":100
         }
      },
      { 
         "lookups":{ 
            "User Profile":{ 
               "p_0":"Resident", "p_1":"Worker", "p_2":"Visitor"
            },
            "Age Group":{ 
               "a_0":"0 to 14", "a_1":"15 to 30", "a_2":"30 to 45", "a_3":"45 to 60", "a_4":"60 plus"
            },
            "Prosperity Band":{ 
               "w_0":"very low", "w_1":"low", "w_2":"medium", "w_3":"high"
            },
            "Visits":{ 
               "v_0":"total"
            }
         }
      },
      { 
         "features":[ 
            { 
               "properties":{ 
                  "h3":"83194afffffffff",
                  "v_0":8000, "a_0":2000, "a_1":0, "a_2":2000, "a_3":0, "a_4":4000,
                  "w_0":2000, "w_1":2000, "w_2":1000, "w_3":3000, "p_0":3000, "p_1":0, "p_2":5000
               },
               "type":"Feature"
            },
            { 
               "properties":{ 
                  "h3":"83194efffffffff",
                  "v_0":42879000, "a_0":13189000, "a_1":726000, "a_2":20372000, "a_3":1550000, "a_4":6828000,
                  "w_0":6604000, "w_1":17373000, "w_2":10544000, "w_3":8144000, "p_0":27705000, "p_1":2180000, "p_2":12994000
               },
               "type":"Feature"
            }
         ],
         "type":"FeatureCollection"
      }
   ]
}

我可以使用此代码访问元数据元素:

dynamic dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseBody);
foreach (var layer in dynObj.layers)
{
   _numCells = (int)layer["metadata"]["cells"].ToObject<int>();
   _numRecords = (int)layer["metadata"]["records"].ToObject<int>();
   _queryTime = (string)layer["metadata"]["query"].ToObject<string>();
   _sample = (int)layer["metadata"]["sample"].ToObject<int>();
   _calibrate = (int)layer["metadata"]["calibrate"].ToObject<int>();
}

但是当我尝试访问任何剩余元素时,我得到一个 Null 异常。让我使用用户配置文件元素来展示我的工作。第一个与上面类似:

dynamic dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseBody);
foreach (var layer in dynObj.layers)
{
   _numCells = (int)layer["metadata"]["cells"].ToObject<int>();
   _numRecords = (int)layer["metadata"]["records"].ToObject<int>();
   _queryTime = (string)layer["metadata"]["query"].ToObject<string>();
   _sample = (int)layer["metadata"]["sample"].ToObject<int>();
   _calibrate = (int)layer["metadata"]["calibrate"].ToObject<int>();

   string group = "User Profile";

   for (int i = 0; ; i++)
   {
      string col = String.Format("p_{0}", i.ToString());
      string descr = (string)layer["lookups"][group][col].ToObject<string>();
      if (descr == string.Empty)
         break;

      _lstColGroup.Add(group);
      _lstColNames.Add(col);
      _lstColDescriptions.Add(descr);
   }
}

每个查找组中的元素数量可能会发生变化,因此我从 0 开始循环,直到得到一个空的描述。

也许有更好的方法来做到这一点?

最佳答案

由于您循环遍历对象,因此当迭代当前位于“元数据”子级时,您无法访问“查找”。因此在访问数据之前需要进行检查:

Newtonsoft.Json.Linq.JObject obj = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(responseBody);
foreach (var item in obj.SelectToken("layers"))
{
    if (item.SelectToken("metadata") != null) { // Stuff with metadata }
    if (item.SelectToken("lookups") != null) { // Stuff with lookups }
    if (item.SelectToken("features") != null) { // Stuff with features }
}

但我强烈建议为您的 Json 解析创建一个模型,这将使​​您的生活更轻松。

关于c# - 使用 Newtonsoft 解析 json 字符串会引发 Null 引用执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58554892/

相关文章:

c# - 我可以仅使用套接字在 Java 和 C# 之间进行通信吗?

c# - 为什么 x++-+-++x 合法但 x+++-+++x 不合法?

javascript - AngularJS,Ng-repeat 更改/更改 Json 数组的顺序

json - Xamarin + JSON.Net

c# - 一次移动两个 WPF 窗口?

c# - 通过用户名和密码从 Azure Ad 获取 AccessToken

javascript - 如何向(JSON)对象的原型(prototype)添加方法?

php - 在 cakePHP 中 json 序列化后回显一些内容

razor - 如何从设置 json 获取数据到 mvc 6 View ?

c#-4.0 - 通用 XML 序列化程序,但不适用于 JObject