【问题标题】:Read REST API JSON reply阅读 REST API JSON 回复
【发布时间】:2021-03-02 22:08:05
【问题描述】:

我一直在网络上来回搜索,但找不到关于我的问题的提示。

我正在通过 RestSharp Client 调用 REST API。我检索到这样的响应:

{
 "meta": {
  "query_time": 0.007360045,
  "pagination": {
   "offset": 1,
   "limit": 100,
   "total": 1
  },
  "powered_by": "device-api",
  "trace_id": "a0d33897-5f6e-4799-bda9-c7a9b5368db7"
 },
 "resources": [
  "1363bd6422274abe84826dabf20cb6cd"
 ],
 "errors": []
}

我现在想查询resources的值。这是我使用的代码:

Dim id_request = New RestRequest("/devices/queries/devices/v1?filter=" + filter, Method.GET)
id_request.AddHeader("Accept", "application/json")
id_request.AddHeader("Authorization", "bearer " + bearer)
Dim data_response = data_client.Execute(id_request)
Dim data_response_raw As String = data_response.Content
Dim raw_id As JObject = JObject.Parse(data_response_raw)
Dim id = raw_id.GetValue("resources").ToString

很遗憾,我收到的只是["1363bd6422274abe84826dabf20cb6cd"],而不是1363bd6422274abe84826dabf20cb6cd

谁能指出我正确的方向?

我也尝试使用JsonConvert.DeserializeObject() 反序列化,但不知何故失败了。

我在这里找到了这个解决方案,但如果我尝试重建它会失败,因为它无法识别字典部分

 Dim tokenJson = JsonConvert.SerializeObject(tokenJsonString)
 Dim jsonResult = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(jsonString)
 Dim firstItem = jsonResult.Item("data").Item(0)

编辑:

当尝试按照建议反序列化根时,但似乎第二个响应是嵌套的 JSON。

我有这样的回复:

dr = {
     "meta": {
      "query_time": 0.004813129,
      "powered_by": "device-api",
      "trace_id": "5a355c86-37f7-416d-96c4-0c8796c940fc"
     },
     "resources": [
      {
       "device_id": "1363bd6422274abe84826dabf20cb6cd",
       "policies": [
        {
         "policy_type": "prevention",
         "policy_id": "1d34205a4e2c4d1991431c037c8e5734",
         "applied": true,
         "settings_hash": "7cb00a74",
         "assigned_date": "2021-02-22T13:56:37.759459481Z",
         "applied_date": "2021-02-22T13:57:19.962692301Z",
         "rule_groups": []
        }
       ],
       "meta": {
        "version": "352"
       }
      }
     ],
     "errors": []
    }

我试过了:

Dim restApiResponse = JsonConvert.DeserializeObject(Of RestApiResponseRoot)(dr)
' This is your array of strings
Dim resources = restApiResponse.Resources

不幸的是,我得到了 Newtonsoft.Json.JsonReaderException: '解析值时遇到意外字符: {.路径“资源”,第 8 行,位置 3。

【问题讨论】:

    标签: json vb.net api json.net rest-client


    【解决方案1】:

    资源属性是一个数组。像往常一样,您需要指定要考虑的数组元素。在这种情况下,第一个,即索引 0 处的元素。

    Dim jsonObject = JObject.Parse(data_response_raw)
    Dim firstResource = jsonObject("resources")(0).ToString()
    

    如果您希望将数组内容作为 String 数组,而不仅仅是第一个元素 - 假设 resources 可以包含多个字符串(毕竟它是一个数组) - 反序列化为 String()

    Dim jsonObject = JObject.Parse(data_response_raw)
    Dim resources = JsonConvert.DeserializeObject(Of String())(jsonObject("resources").ToString())
    

    如果您需要整个 JSON 响应,我建议反序列化为代表 JSON 的类 Model:

    Public Class RestApiResponseRoot
        Public Property Meta As Meta
        Public Property Resources As List(Of String)
        Public Property Errors As List(Of Object)
    End Class
    Public Class Meta
        <JsonProperty("query_time")>
        Public Property QueryTime As Double
        Public Property Pagination As Pagination
        <JsonProperty("powered_by")>
        Public Property PoweredBy As String
        <JsonProperty("trace_id")>
        Public Property TraceId As Guid
    End Class
    Public Class Pagination
        Public Property Offset As Long
        Public Property Limit As Long
        Public Property Total As Long
    End Class
    

    然后您可以反序列化模型的 Root 对象(此处名为 RestApiResponseRoot 的类)并照常访问其属性:

    Dim restApiResponse = JsonConvert.DeserializeObject(Of RestApiResponseRoot)(
        data_response_raw
    )
    ' This is your array of strings
    Dim resources = restApiResponse.Resources
    

    另一个 JSON 响应略有不同,响应属性包含对象数组而不是字符串。
    添加了更多属性和嵌套对象。你只需要调整模型。

    Public Class RestApiResponseRoot2
        Public Property Meta As RootObjectMeta
        Public Property Resources As List(Of Resource)
        Public Property Errors As List(Of Object)
    End Class
    
    Public Class RootObjectMeta
        <JsonProperty("query_time")>
        Public Property QueryTime As Double
        <JsonProperty("powered_by")>
        Public Property PoweredBy As String
        <JsonProperty("trace_id")>
        Public Property TraceId As Guid
    End Class
    
    Public Class Resource
        <JsonProperty("device_id")>
        Public Property DeviceId As String
        Public Property Policies As List(Of Policy)
        Public Property Meta As ResourceMeta
    End Class
    
    Public Class ResourceMeta
        Public Property Version As String
    End Class
    
    Public Class Policy
        <JsonProperty("policy_type")>
        Public Property PolicyType As String
        <JsonProperty("policy_id")>
        Public Property PolicyId As String
        Public Property Applied As Boolean
        <JsonProperty("settings_hash")>
        Public Property SettingsHash As String
        <JsonProperty("assigned_date")>
        Public Property AssignedDate As DateTimeOffset
        <JsonProperty("applied_date")>
        Public Property AppliedDate As DateTimeOffset
        <JsonProperty("rule_groups")>
        Public Property RuleGroups As List(Of Object)
    End Class
    

    Dim restApiResponse2 = JsonConvert.DeserializeObject(Of RestApiResponseRoot2)(dr)
    Dim resources As List(Of Resource) = restApiResponse2.Resources
    ' DeviceId of the first Resources object
    Dim deviceId = resources(0).DeviceId
    

    您可以使用一些在线资源来处理您的 JSON 对象:

    JSON Formatter & Validator

    QuickType - JSON 到 .Net 类 - C#,没有 VB.Net

    JSON Utils - JSON 到 .Net 类 - 包括 VB.Net。 能力比 QuickType 稍差。

    【讨论】:

    • 您好 Jimi,非常感谢您!我会分析并回复:) 非常感谢!
    • Jimi,工作起来就像一个魅力 :) 我也尝试按照建议反序列化根,但似乎第二个响应是嵌套的 JSON
    • 嗨 Jimi,是的,非常感谢你!我已经用我得到的第二个回复更新了实际问题 - 我查询的越多,回复似乎就越复杂。再次感谢您的帮助!
    • 吉米这是一个非常棒的回应!想我现在明白了 - 非常感谢!
    【解决方案2】:

    尝试在输出的第一个和最后一个使用 " 字符来修剪资源值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-26
      • 2017-08-03
      • 2017-06-27
      相关资源
      最近更新 更多