【问题标题】:Trouble getting at values in JSON with json.net in c#在 c# 中使用 json.net 获取 JSON 中的值时遇到问题
【发布时间】:2020-03-12 19:26:00
【问题描述】:

我正在尝试将RESTFUL API 用于我们内部使用的应用程序。对 API 的一次调用会返回以下 JSON

{
    "operation": {
        "name": "GET RESOURCES",
        "result": {
            "status": "Success",
            "message": "Query was successful"
        },
        "totalRows": 2,
        "Details": [{
            "RESOURCE DESCRIPTION": "Windows",
            "RESOURCE TYPE": "Windows",
            "RESOURCE ID": "101",
            "RESOURCE NAME": "WINDOWSPC",
            "NOOFACCOUNTS": "1"
        }, {
            "RESOURCE DESCRIPTION": "Ubuntu",
            "RESOURCE TYPE": "Linux",
            "RESOURCE ID": "808",
            "RESOURCE NAME": "UBUNTUPC",
            "NOOFACCOUNTS": "2"
        }]
    }
}

使用 json.net 我反序列化 json 并使用以下行检查统计信息:

dynamic json = JsonConvert.DeserializeObject(response);
var status = json.operation.result.status.Value;

接下来我想获取返回的每个“详细信息”的每个值,但我不知道如何。我首先尝试仅通过以下方式获取详细信息:

var resourceList = json.operation.Details

这可行,但我不能通过迭代来获取例如“资源 ID”和“资源名称”。

我也不能使用.Children(),但是当我将鼠标悬停在资源列表上时,有一个ChildrenTokens,这似乎是我想要的,但我无法在我的代码中找到它。

我还尝试按照他们的exampleresourceList 用作数据集,但它会引发异常。

谁能看到我做错了什么.....我不熟悉用 C# 解析 JSON

【问题讨论】:

  • 复制您的 JSON 字符串然后使用选择性粘贴(编辑 -> 选择性粘贴 -> 将 JSON 粘贴为类),它将为您生成所有必要的类。
  • @SᴇM 这听起来像是我可以使用的东西......但在我的 VS2019 社区中,我没有那个选项......
  • @neildeadman 你知道,它在所有版本中都可用。在 C# 文件中,转到 Edit 菜单并打开 Paste Special 子菜单。该选项不会出现在其他文本文件中
  • 一旦你定义了类,你可以简单地使用DeserializeObject<T> 和你的类。 newtonsoft.com/json/help/html/DeserializeObject.htm
  • 这能回答你的问题吗? Deserialize JSON into Object C#

标签: c# json json.net


【解决方案1】:

您可以为此使用Json.Linq 并将响应解析为JObject,然后对其进行迭代foreach 循环。这是可能的,因为Details 是一个数组,而JObject 实现了IDictionary<string, JToken>IEnumerable<KeyValuePair<string, JToken>>

var jObject = JObject.Parse(response);

foreach (var detail in jObject["operation"]["Details"])
{
    var description = detail["RESOURCE DESCRIPTION"].Value<string>();
    //other properties
}

【讨论】:

    【解决方案2】:

    这是一个使用JObject 类而不是dynamic 的示例

    JObject json = JObject.Parse(response);
    
    string status = json["operation"]["result"]["status"].Value<string>();
    
    foreach (JToken resource in json["operation"]["Details"])
    {
        string id = resource["RESOURCE ID"].Value<string>();
        string name = resource["RESOURCE NAME"].Value<string>();
    }
    

    【讨论】:

      【解决方案3】:

      就这么简单:

      您的模型类如下所示:

      public class Result
      {
          public string status { get; set; }
          public string message { get; set; }
      }
      
      public class Detail
      {
          [JsonProperty("RESOURCE DESCRIPTION")]
          public string ResourceDescription { get; set; }
          [JsonProperty("RESOURCE TYPE")]
          public string ResourceType { get; set; }
          [JsonProperty("RESOURCE ID")]
          public string ResourceId { get; set; }
          [JsonProperty("RESOURCE NAME")]
          public string ResourceName { get; set; }
          [JsonProperty("NOOFACCOUNTS")]
          public string NoOfAccounts { get; set; }
      }
      
      public class Operation
      {
          public string name { get; set; }
          public Result result { get; set; }
          public int totalRows { get; set; }
          public List<Detail> Details { get; set; }
      }
      
      public class RootObject
      {
          public Operation operation { get; set; }
      }
      

      反序列化:

      var json = JsonConvert.DeserializeObject<RootObject>(response);
      

      访问属性:

      var name=json.operation.name
      

      访问您的Details

      foreach(var item in json.operation.Details)
      {
      var myresourcename=item.ResourceName;
      //So on
      }
      

      【讨论】:

      • 谢谢,其他答案较短,但我会进一步研究。
      • 我也会使用这种方法,因为您不必弄乱字符串(更少的错误、IntelliSense 支持等)。
      • 所以另一个 API 调用返回一个不同的 JSON,它也有 Operation,但缺少 TotalRows 字段。我最好为每个类实现一个不同的类,还是我可以实现多个相似的类等。
      • 是的,您可以将此类用于其他 API 响应。基本上,您可以为基本 API 响应定义模型结构,并为内部响应使用继承概念。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 2016-08-26
      • 1970-01-01
      相关资源
      最近更新 更多