I have been searching the web back an forth but couldn't find a hint to my issue.
I'm calling a REST API via RestSharp Client
. I retrieve a response like this:
{
"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": []
}
I want to query the value of resources
at the moment. This is the code I use:
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
Unfortunately, I'm only getting ["1363bd6422274abe84826dabf20cb6cd"]
as a reply instead of 1363bd6422274abe84826dabf20cb6cd
Can anyone point me into the right direction?
I have also tried to deserialize using JsonConvert.DeserializeObject()
but I somehow fail.
I found this solution here but if I try to rebuild it fails as it doesn't recognize the Dictionary part
Dim tokenJson = JsonConvert.SerializeObject(tokenJsonString)
Dim jsonResult = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(jsonString)
Dim firstItem = jsonResult.Item("data").Item(0)
EDIT:
When trying to deserialize the root as suggested but seems as if the 2nd response is nested JSON.
I have a reply like:
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": []
}
and I tried:
Dim restApiResponse = JsonConvert.DeserializeObject(Of RestApiResponseRoot)(dr)
' This is your array of strings
Dim resources = restApiResponse.Resources
Unfortunately I get Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: {. Path 'resources', line 8, position 3.'
The resources Property is an array. As usual, you need to specify which element of the array you want to consider. In this case, the first one, i.e., the element at index 0
.
Dim jsonObject = JObject.Parse(data_response_raw)
Dim firstResource = jsonObject("resources")(0).ToString()
If you instead want the array content as a String array, not just the first element - assuming resources
could contain more than one string (it's an array after all) - deserialize to String()
:
Dim jsonObject = JObject.Parse(data_response_raw)
Dim resources = JsonConvert.DeserializeObject(Of String())(jsonObject("resources").ToString())
In case you need the whole JSON response, I suggest to deserialize to a class Model that represents the JSON:
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
You can then deserialize the Model's Root object - the class named RestApiResponseRoot
here - and access its Properties as usual:
Dim restApiResponse = JsonConvert.DeserializeObject(Of RestApiResponseRoot)(
data_response_raw
)
' This is your array of strings
Dim resources = restApiResponse.Resources
The other JSON response is slightly different, the Response Property contains an array of objects instead of string.
Some more properties and nested object are added. You just need to adjust the Model.
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
You can use some on-line resources to handle your JSON objects:
QuickType - JSON to .Net classes - C#, no VB.Net
JSON Utils - JSON to .Net classes - includes VB.Net. Somewhat less capable than QuickType.