I am new to Vb.net. Having a JSON string as given below, I tries to deserialize the JSON into an Object using JsonConvert.DeserializeObject().
I am trying to loop values inside the Content object in the given JSON to fetch its values.
I tried using a for loop, but I'm not able to get the exact values.
Dim result As String = {
"status": "0001",
"Result": {
"IsError": "0",
"Data": {
"Type": "a",
"Header": [
"v1",
"v2",
"v3",
"v4",
"v5"
],
"Content": [
[
"001",
"Raj",
"1",
"N",
""
],
[
"002",
"Vignesh",
"1",
"N",
""
],
[
"778",
"Ramesh",
"1",
"N",
""
],
[
"792",
"Suresh",
"1",
"N",
""
],
[
"703",
"Karthick",
"1",
"N",
""
],
[
"1247",
"Ram",
"1",
"N",
""
]
]
}
}
}
Dim jsonResult2 = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(result)
If you just want to deserialize the Content array, you can parse the JSON with JToken.Parse(), then deserialize to a List(Of String()) that section only.
Dim jsonResult = JToken.Parse(result)
Dim content = JsonConvert.DeserializeObject(Of List(Of String()))(
jsonResult("Result")("Data")("Content").ToString()
)
Or, you could use a class Model to deserialize the whole JSON, then access each object as a standard .Net Property value.
Public Class StatusResultsRoot
<JsonProperty("status")>
Public Property Status As String
Public Property Result As Result
End Class
Public Partial Class Result
Public Property IsError As String
Public Property Data As Data
End Class
Public Partial Class Data
<JsonProperty("Type")>
Public Property DataType As String
Public Property Header As List(Of String)
Public Property Content As List(Of String())
End Class
'[...]
Dim statusResult = JsonConvert.DeserializeObject(Of StatusResultsRoot)(result)
The Content List is then
Dim content As List(Of String()) = statusResult.Result.Data.Content
' Loop the List of String(), print the combined array of strings
For Each stringArray As String() In content
Console.WriteLine(String.Join(", ", stringArray))
Next
In case you actually want to embed a JSON as a string, you can use an XML element literal, defining an XElement by enclosing the JSON with <node> ... </node> markers.
You can then paste in the JSON as is (no need to double the double-quotes).
The JSON is then the string representation of the first node of the XElement: i.e., [XElement].FirstNode.ToString(). For example:
Dim xResult = <json> {
"status": "0001",
"Result": {
"IsError": "0",
"Data": {
' [... other content ...]
}
}
} </json>
Dim json As String = xResult.FirstNode.ToString()
You cannot do this in C#.
A string in VB must begin and end with a ".
The inner double quotes should be replaced with "".
So a proper string(when assigning it in code) would look like:
Dim result as string = "{
""status"": ""0001"",
...
}
"
Related
I'm having an issue with a JSON property name. It might be because I don't know what I'm doing. This is my 1st attempt at serializing JSON (with vb.net VB)
The result I'm looking for is this:
{
"login": {
"username": "XXX",
"password": "pwxXXxx",
"busId": "123456789",
"busRole": "Third Party",
"paymentTerms": "Prepaid"
}
}
This is what I am getting:
[
{
"login": null,
"username": "1234",
"password": "pw123456",
"busId": "12345",
"busRole": "Third Party",
"paymentTerms": "Prepaid"
}
]
My issue is with the piece "login": {" adds the colon and the term null. I'll post my code below
Any help would be appreciated.
-Thank You
Partial Class _Default
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim loads As New List(Of fgtload)()
loads.Add(New fgtload() With {
.username = "1234",
.password = "pw123456",
.busId = "12345",
.busRole = "Third Party",
.paymentTerms = "Prepaid"
}
)
Dim strserialize As String = JsonConvert.SerializeObject(loads)
lblserial.Text = strserialize
End Sub
Public Class fgtload
<JsonProperty(PropertyName:="login")>
Public Property login As String
Public Property username() As String
Get
Return m_username
End Get
Set
m_username = Value
End Set
End Property
Private m_username As String
Public Property password() As String
Get
Return m_password
End Get
Set
m_password = Value
End Set
End Property
Private m_password As String
Public Property busId() As String
Get
Return m_busId
End Get
Set
m_busId = Value
End Set
End Property
Private m_busId As String
Public Property busRole() As String
Get
Return m_busRole
End Get
Set
m_busRole = Value
End Set
End Property
Private m_busRole As String
Public Property paymentTerms() As String
Get
Return m_paymentTerms
End Get
Set
m_paymentTerms = Value
End Set
End Property
Private m_paymentTerms As String
End Class
Here's the entire JSON output sampel Im trying to get.
{
"login": {
"username": "XXX",
"password": "pwxXXxx",
"busId": "123456789",
"busRole": "Third Party",
"paymentTerms": "Prepaid"
}
}
,
"details": {
"serviceClass": "STD",
"typeQuery": "QUOTE",
"pickupDate": "20200221",
"productCode": "DFQ"
},
"originLocation": {
"city": "Keyport",
"state": "NJ",
"postalCode": "07735",
"country": "USA",
"locationType": "COMM"
},
"destinationLocation": {
"city": "Beverly Hills",
"state": "CA",
"postalCode": "90210",
"country": "USA",
"locationType": "COMM"
},
"listOfCommodities": {
"commodity": [
{
"packageLength": 48,
"packageWidth": 48,
"packageHeight": 48,
"weight": 1500,
"handlingUnits": 1,
"packageCode": "PLT"
}
]
}
}
How would I add another class to the wrapper. For example
Public Class fgtDetails '
Public ServiceClass As String
Public typeQuery As String
Public pickupDate As Integer
Public productCode As String
End Class
From what I can see, you are trying to declare the login element as an empty string and is therefore serialized as null. From what you said you are trying to achieve, you want to declare login as an object that contains the Username, Password, BusID, BusRole, and PaymentTerms properties.
From what your looking for, the Login property is an object, but you are declaring it as a string. Also, you are creating a list and serializing that, which is leading to those square brackets ([, ]) around your JSON. Square brackets mark arrays or enumerations, whereas in your sample JSON you are just looking for an object.
One last tip, for classes that are used for serializing, you don't have to use properties. You can just declare your variables as public variables. The only time you need to use properties is if you need to modify or do something with its contents when it's being set or read. e.g., formatting a string when it's being set, or calculating a response when the variable is being retrieved (you can put code in the GET and SET methods to make them act like a function).
Something to note with serializing and deserializing, you can nest classes. When serialized they will be converted to JSON objects using the same object layout and variable name. So you can try something like this:
(UPDATED CODE)
Public Sub CreateJson()
'Create Wrapper Object
Dim Load As New fgtload
Load.Login = New fgtLoginData With { 'Create Login Data
.Username = "XXX",
.Password = "pwxXXxx",
.BusID = 123456789,
.BusRole = "Third Party",
.PaymentTerms = "Prepaid"
}
Load.Details = New fgtDetailsData With { 'Create Details
.ServiceClass = "STD",
.TypeQuery = "QUOTE",
.PickupDate = "20200221",
.ProductCode = "DFQ"
}
Load.OriginLocation = New fgtLocationnData With { 'Create Origin
.City = "Keyport",
.State = "NJ",
.PostalCode = 7735,
.Country = "USA",
.LocationType = "COMM"
}
Load.DestinationLocation = New fgtLocationnData With { 'Create Destination
.City = "Beverly Hills",
.State = "CA",
.PostalCode = 90210,
.Country = "USA",
.LocationType = "COMM"
}
'Create Commodities
Dim Commodity1 As New fgtCommodity With {
.PackageLength = 48,
.PackageWidth = 48,
.PackageHeight = 48,
.Weight = 1500,
.HandlingUnits = 1,
.PackageCode = "PLT"
}
'Add commodity to load
Load.ListOfCommodities.commodity.Add(Commodity1)
'Serialize wrapper object
Dim Json As String = JsonConvert.SerializeObject(Load)
End Sub
Public Class fgtload 'Primary wrapper
Public Login As New fgtLoginData
Public Details As New fgtDetailsData
Public OriginLocation As New fgtLocationnData
Public DestinationLocation As New fgtLocationnData
Public ListOfCommodities As New fgtCommodityWrapper
End Class
Public Class fgtLoginData 'Login Data
Public Username As String
Public Password As String
Public BusID As String
Public BusRole As String
Public PaymentTerms As String
End Class
Public Class fgtDetailsData 'Details Data
Public ServiceClass As String
Public TypeQuery As String
Public PickupDate As String
Public ProductCode As String
End Class
Public Class fgtLocationnData 'Location data for both Origin and Destination
Public City As String
Public State As String
Public PostalCode As String
Public Country As String
Public LocationType As String
End Class
Public Class fgtCommodityWrapper 'Commodity Data
Public commodity As New List(Of fgtCommodity) ' Lists get serialized into arrays
End Class
Public Class fgtCommodity
Public PackageLength As Double 'Doubles to allow floating-point numbers
Public PackageWidth As Double
Public PackageHeight As Double
Public Weight As Double
Public HandlingUnits As Integer
Public PackageCode As String
End Class
This creates this response.
(UPDATED OUTPUT)
{
"Login": {
"Username": "XXX",
"Password": "pwxXXxx",
"BusID": "123456789",
"BusRole": "Third Party",
"PaymentTerms": "Prepaid"
},
"Details": {
"ServiceClass": "STD",
"TypeQuery": "QUOTE",
"PickupDate": "20200221",
"ProductCode": "DFQ"
},
"OriginLocation": {
"City": "Keyport",
"State": "NJ",
"PostalCode": "7735",
"Country": "USA",
"LocationType": "COMM"
},
"DestinationLocation": {
"City": "Beverly Hills",
"State": "CA",
"PostalCode": "90210",
"Country": "USA",
"LocationType": "COMM"
},
"ListOfCommodities": {
"commodity": [
{
"PackageLength": 48.0,
"PackageWidth": 48.0,
"PackageHeight": 48.0,
"Weight": 1500.0,
"HandlingUnits": 1,
"PackageCode": "PLT"
}
]
}
}
Hope this helps.
(UPDATE NOTES):
In response to your comment, I have modified the code in my response to allow or your updated expected output.
Note also that if two JSON objects have the same structure (in this case originLocation and destinationLocation) you can use the same class.
Also, see at the Commodity Data there are square brackets, this marks a JSON array. Arrays/Lists/Enumerations in your code will be serialized into JSON arrays, even if they are of a class type. So in this code example, you can add as many commodities to ListOfCommodities.commodity as you want and they will be properly serialized into JSON.
I have a Json Data. Trying to convert it into Datatable using Newtonsoft. But It is giving Me Error :
An exception of type 'Newtonsoft.Json.JsonSerializationException'
occurred in Newtonsoft.Json.dll but was not handled in user code
JSon Data :
{
"items": [
{
"id": "4",
"order_id": "000000145",
"creditmemo": {
"items": [
{
"sku": "SWETA0582",
"product_id": "2640",
"item_id": "211",
"qty": "1.0000",
"reason": "Product didn’t meet your expectation."
},
{
"sku": "SWETA0583",
"product_id": "2642",
"item_id": "212",
"qty": "2.0000",
"reason": "Product didn’t meet your expectation."
}
],
"do_offline": 1,
"comment_text": "",
"shipping_amount": "49.0000",
"adjustment_positive": "",
"adjustment_negative": "49.0000"
},
"additional_remark": "",
"type": "1",
"status": "3",
"account": {
"ifsc": "PYTM0123456",
"account_no": "918981961927",
"name": "Shruti Dhandhania"
},
"refund_status": "0",
"totals_info": "",
"refund_id": "0",
"created_at": "2018-10-25 08:58:37",
"update_at": "2018-10-25 08:58:37",
"tracking_number": "",
"method": "cashondelivery",
"comment": null
},
{
"id": "5",
"order_id": "000000146",
"creditmemo": {
"items": [
{
"sku": "SWETA0584",
"product_id": "2644",
"item_id": "215",
"qty": "3.0000",
"reason": "Product didn’t meet your expectation."
},
{
"sku": "SWETA0585",
"product_id": "2646",
"item_id": "216",
"qty": "2.0000",
"reason": "Product didn’t meet your expectation."
}
],
"do_offline": 1,
"comment_text": "",
"shipping_amount": "49.0000",
"adjustment_positive": "",
"adjustment_negative": "49.0000"
},
"additional_remark": "",
"type": "1",
"status": "3",
"account": {
"ifsc": "PYTM0123456",
"account_no": "918981961927",
"name": "Shruti Dhandhania"
},
"refund_status": "0",
"totals_info": "",
"refund_id": "0",
"created_at": "2018-10-25 08:58:37",
"update_at": "2018-10-25 08:58:37",
"tracking_number": "",
"method": "cashondelivery",
"comment": null
}
]
}
Vb.Net Code :
Protected Sub Button1_Click(sender As Object, e As EventArgs)
Dim dataSet = JsonConvert.DeserializeObject(Of DataSet)(TextBox1.Text)
Dim table = dataSet.Tables(0)
End Sub
Showing Error :
An exception of type 'Newtonsoft.Json.JsonSerializationException'
occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Unexpected JSON token when reading DataTable:
StartObject. Path 'items[0].creditmemo', line 6, position 21.
Your JSON structure is not a array of simple key value pair but is an object. For de-serializing this, you'll need to :
Create a class for your deserialized data.
Do this:
YourClass yourObject = JsonConvert.DeserializeObject<YourClass>(jsonStr);
I solved my problem.
Partial Class Default2
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs)
Dim js As JavaScriptSerializer = New JavaScriptSerializer()
Dim response As RootObject = js.Deserialize(Of RootObject)(txtJsonData.Text)
Dim dset = New DataSet()
AddToDataSet(dset, response, Nothing, Nothing)
For Each itm In response.items
AddToDataSet(dset, itm.account, itm.order_id, "order_id")
Next
For Each itm In response.items
AddToDataSet(dset, itm.creditmemo, itm.order_id, "order_id")
Next
Dim dt As DataSet = dset
End Sub
Public Sub AddToDataSet(ByVal dset As DataSet, ByVal value As Object, ByVal strprimaryColValue As String, ByVal primaryColName As String)
'If dset Is Nothing Then Throw New ArgumentNullException(NameOf(dset))
Dim mprimaryColValue As String
Dim mprimaryColName As String
mprimaryColValue = strprimaryColValue
mprimaryColName = primaryColName
If value Is Nothing Then Return
Dim type = value.[GetType]()
Dim table = dset.Tables(type.FullName)
If table Is Nothing Then
table = New DataTable(type.FullName)
dset.Tables.Add(table)
For Each prop In type.GetProperties().Where(Function(p) p.CanRead)
If IsEnumerable(prop) Then Continue For
Dim col = New DataColumn(prop.Name, prop.PropertyType)
table.Columns.Add(col)
If strprimaryColValue IsNot Nothing Then
If Not table.Columns.Contains(primaryColName) Then
table.Columns.Add(primaryColName)
End If
End If
Next
End If
Dim row = table.NewRow()
For Each prop In type.GetProperties().Where(Function(p) p.CanRead)
Dim propValue As Object = prop.GetValue(value)
If IsEnumerable(prop) Then
If propValue IsNot Nothing Then
For Each child In CType(propValue, ICollection)
AddToDataSet(dset, child, mprimaryColValue, mprimaryColName)
Next
End If
Continue For
End If
row(prop.Name) = propValue
If strprimaryColValue IsNot Nothing Then
If table.Columns.Contains(primaryColName) Then
row(primaryColName) = strprimaryColValue
End If
End If
Next
table.Rows.Add(row)
End Sub
Private Function IsEnumerable(ByVal pi As PropertyInfo) As Boolean
Return GetType(ICollection).IsAssignableFrom(pi.PropertyType)
End Function
End Class
Public Class Products
Public Property sku As String
Public Property product_id As String
Public Property item_id As String
Public Property qty As String
Public Property reason As String
End Class
Public Class Creditmemo
Public Property items As List(Of Products)
Public Property do_offline As Integer
Public Property comment_text As String
Public Property shipping_amount As String
Public Property adjustment_positive As String
Public Property adjustment_negative As String
End Class
Public Class Account
Public Property ifsc As String
Public Property account_no As String
Public Property name As String
End Class
Public Class Orders
Public Property id As String
Public Property order_id As String
Public Property creditmemo As Creditmemo
Public Property additional_remark As String
Public Property type As String
Public Property status As String
Public Property account As Account
Public Property refund_status As String
Public Property totals_info As String
Public Property refund_id As String
Public Property created_at As String
Public Property update_at As String
Public Property tracking_number As String
Public Property method As String
Public Property comment As Object
End Class
Public Class RootObject
Public Property total_size As Integer
Public Property items As List(Of Orders)
End Class
I have the following JSON object:-
Public Class oPartner
Public Property PartnerID() As String
Public Property PartnerTitle() As String
Public Property PartnerStrapline() As String
Public Property PartnerData() As String
End Class
And the following partners.json JSON file:-
[
{
"PartnerID": "1",
"PartnerTitle": "TITLE1",
"PartnerStrapline": "STRAP1",
"PartnerData": "SOME INFO IN HERE",
"PartnerImage": ""
},
{
"PartnerID": "2",
"PartnerTitle": "TITLE2",
"PartnerStrapline": "STRAP2",
"PartnerData": "SOME MORE INFO IN HERE",
"PartnerImage": ""
},
{
"PartnerID": "3",
"PartnerTitle": "TITLE3",
"PartnerStrapline": "STRAP3",
"PartnerData": "MORE INFO",
"PartnerImage": ""
}
]
So I can read the JSON and deserialize using:-
Dim data As oPartner = JsonConvert.DeserializeObject(Of oPartner)(File.ReadAllText("c:\partners.json"))
But I can't work out how I would loop through the json in vb (or C#)?
Your JSON represents an array of objects, but you are trying to deserialize it into a single instance. You need to deserialize into an array (or List) of oPartner instead. Try it like this:
Dim data As List(Of oPartner) = JsonConvert.DeserializeObject(Of List(Of oPartner))(File.ReadAllText("c:\partners.json"))
Then you can loop through the list like this:
For Each partner As oPartner In data
Console.WriteLine(partner.PartnerID)
Console.WriteLine(partner.PartnerTitle)
Console.WriteLine(partner.PartnerStrapline)
Console.WriteLine(partner.PartnerData)
Console.WriteLine()
Next
Fiddle: https://dotnetfiddle.net/N8Im6q
The code I have to work with is Visual Basic. I have JSON that needs to be deserialized to an object.
I am running into the error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type System.Collections.Generic.List1[AgentGroup] because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '[0].agentGroup.id', line 3, position 7
Now what I've done is instantiated the object, serialized it and write to a text file so that I can see how that data looks in JSON, which came out to this:
{
"agentGroup": [
{
"Id": 6873450,
"GroupName": "sig_latam_buenosaires",
"Fields": {
"Organization": "Football_Inc",
"LoadBalanced": "No",
"Description": "bye",
"TransferConcurrency": "",
"IsMxEnabled": false
}
},
{
"Id": 6873450,
"GroupName": "latam_buenosaires",
"Fields": {
"Organization": null,
"LoadBalanced": null,
"Description": null,
"TransferConcurrency": null,
"IsMxEnabled": false
}
},
{
"Id": 666,
"GroupName": "NY",
"Fields": {
"Organization": "TechniColor",
"LoadBalanced": "Yes",
"Description": "Hello World",
"TransferConcurrency": "",
"IsMxEnabled": true
}
}
]
}
But what the JSON I need to deserialize is in this format:
[{
"agentGroup": {
"id": 9943652,
"groupName": "technicolorBangalore",
"fields": {
"organization": "TechniColor",
"loadBalanced": "Yes",
"description": "Technicolor Bangalore Agents",
"mxEnabled": false,
"transferConcurrency": null
}
}
}, {
"agentGroup": {
"id": 6873450,
"groupName": "sig_latam_buenosaires",
"fields": {
"organization": "Viacom_Inc",
"loadBalanced": "No",
"description": "",
"mxEnabled": false,
"transferConcurrency": null
}
}
}]
I believe it has to do with the beginning square bracket [, I have searched on how to address this issue but being that the code is in Visual Basic, I have not found anything that helps. My code is:
Dim reader As New
StreamReader("C:\Users\poncek\Desktop\SigniantTextFile\AgentGroupList.txt")
Dim jsonString as String = reader.ReadToEnd
Dim works = JsonConvert.DeserializeObject(Of List(Of AgentGroupList))(jsonString)
But this is where the error occurs. I also see that when I write it to the text file my JSON looks different from what I need to deserialize. I am not sure what can be causing this
This sounds a bit simplistic but can you do the following (done with VBA as per tag - oops) ?
Standard module:
Public Sub Example()
Dim JSONString As String
JSONString = Range("A1").Text
Dim JSON As cJSON
Set JSON = New cJSON
Dim D As Dictionary
Set D = JSON.Deserialize(JSONString)
End Sub
And use the class CJSON from here
Code to empty (might need some tidying up - depends if on right lines):
Public Sub Example()
Dim JSONString As String
JSONString = Range("A1").Text 'This holds the original JSON string you provided
Dim JSON As cJSON
Set JSON = New cJSON
Dim D As Dictionary
Set D = JSON.Deserialize(JSONString)
Dim key As Variant
Dim key2 As Variant
Dim key3 As Variant
For Each key In D.Keys
For Each key2 In D(key).Keys
For Each key3 In D(key)(key2)
Select Case TypeName(D(key)(key2)(key3))
Case "Long", "String"
Debug.Print key, key1, key2, key3, D(key)(key2)(key3)
Case "Dictionary"
Dim key4 As Variant
For Each key4 In D(key)(key2)(key3).Keys
Debug.Print key, key1, key2, key3, key4, D(key)(key2)(key3)(key4)
Next key4
End Select
Next key3
Next key2
Next key
End Sub
Output:
So I figured out what was causing the problem. The JSON:
"agentGroup": {
"id": 6873450,
"groupName": "sig_latam_buenosaires",
"fields": {
"organization": "Viacom_Inc",
"loadBalanced": "No",
"description": "",
"mxEnabled": false,
"transferConcurrency": null
}
I already had a VB class called agentField which consisted of 5 properties:
Public Class AgentFields
Public Property Organization() As String
Public Property LoadBalanced() As String
Public Property Description() As String
Public Property TransferConcurrency() As String
Public Property IsMxEnabled() As Boolean
Then another class called AgentGroup:
Public Class AgentGroup
Public Property Id() As Integer
Public Property GroupName() As String
Public Property Fields() As AgentFields
So what I ended up doing was creating a new class to contain the AgentGroup Class:
Public Class Container
Public Property agentGroup() As AgentGroup
Then all I needed to do was create a List of Container:
Dim agentGroupList As New List(Of Container)
So that it can hold all the AgentGroup objects that come in the JSON and when I Deserialize it, it worked perfectly. Since AgentField was used in AgentGroup it as a property the deserialization worked perfectly, all I was missing was a class to contain the AgentGroup class and then create a List to hold all the objects.
OK i know how to parse using newtonsoft.
but I don't know how can i get every value of key inside parsed string
this is the json encoded string
{"result":[{"orderid":"94","imei":"clipper"},{"orderid":"93","item":"shoes"},{"orderid":"92","item":"bag"},{"orderid":"91","item":"shirt"}]}
Dim xreadingJson = Newtonsoft.Json.Linq.JObject.Parse(htmlcode)
Dim resultorder As String = xreadingJson.Item("result").ToString
then the result order is
[
{
"orderid": "94",
"item": "clipper"
},
{
"orderid": "93",
"item": "shoes"
},
{
"orderid": "92",
"item": "shoes"
},
{
"orderid": "91",
"item": "bag"
}
]
On looping how can I get the value of orderid and item.
thank you
Update:
I resolved it using this code
Dim o As JObject = JObject.Parse(htmlcode)
Dim results As List(Of JToken) = o.Children().ToList
For Each item As JProperty In results
item.CreateReader()
'MsgBox(item.Value)
If item.Value.Type = JTokenType.Array Then
For Each subitem As JObject In item.Values
MsgBox(subitem("orderid"))
MsgBox(subitem("item"))
Next
End If
Next
I believe Newtonsoft's JObject has a JObject.GetValue("property_name") method