JSON Encode and Decode with objects in Visual Basic 2010 - json

I have the following code:
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Module Module1
Structure JSONList
Dim Name, Email As String
Dim Age As Integer
End Structure
Sub Main()
Dim Data(1) As JSONList
Data(0).Name = "Josh"
Data(0).Age = 17
Data(0).Email = "me#mail.co.uk"
Data(1).Name = "Greg"
Data(1).Age = 17
Data(1).Email = "greg#hotmail.co.uk"
Dim JSONEncode As String
JSONEncode = JsonConvert.SerializeObject(Data)
Console.WriteLine(JSONEncode)
Console.WriteLine()
Console.WriteLine()
Dim JSONDecode() As JSONList = JsonConvert.DeserializeObject(JSONEncode)
Console.WriteLine(JSONDecode(0).Name)
Console.ReadKey()
End Sub
End Module
The first encoding part of the script is used to store the encoded string to a database, the output is:
[{"Name":"Josh","Email":"me#mail.co.uk","Age":17},{"Name":"Greg","Email":"greg#hotmail.co.uk","Age":17}]
Now when I try to decode this JSON string, I get an error Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'JSONList[]'.
I need the data to be encoded in the JSON format so that I can use it in my website that uses PHP to decode it. I am using Visual Basic 2010 along with JSON.NET.

The problem is that JsonConvert.DeserializeObject deserialises into an object of type Newtonsoft.Json.Linq.JArray which .net cannot automatically convert to an array of JSONList. A little bit of conversion is required:
Dim jsonObject As Newtonsoft.Json.Linq.JArray =
JsonConvert.DeserializeObject(JSONEncode)
Dim JSONDecode() As JSONList = (
From j In jsonObject
Select New JSONList() With {.Age = j("Age"),
.Email = j("Email"),
.Name = j("Name")}
).ToArray()

As #Adrian said, JsonConvert.DeserializeObject will deserialize to JArray, which .Net cannot automatically convert into an array of your JSONList structure. However, you don't need to do manual conversion; you simply need to use the overload of DeserializeObject which accepts a type parameter. This will allow Json.Net to deserialize directly to your type without needing any special conversion code.
Dim JSONDecode() As JSONList = _
JsonConvert.DeserializeObject(Of JSONList())(JSONEncode)

Related

Generation of dynamic class from XML to JSON

What I am trying to achieve is convert XML to a JSON object. Currently I am doing it like this:
Public Class Person
Public Property Name As String
' other properties here'
End Class
Dim doc As XmlDocument
doc.LoadXml(arg_strXml)
Dim jsonValue As String = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JsonConvert.DeserializeObject(Of Person)(jsonValue)
Dim firstName As String = jsonObject.Name
However the issue is the retrieved XML, and thus the deserialized JSON object has different fields/properties/elements depending on the correct function. It would be a nightmare to have a class for each possible XML.
Is there a way round not having to create a specific class (Person in this case) for each deserialize?
You can deserialze/parse your JSON string into Newtonsoft's JObject. Then you can access the properties like Dictionary(Of String, String), for example :
Dim arg_strXml = "<Person><Name>foo</Name></Person>"
Dim doc = New XmlDocument()
doc.LoadXml(arg_strXml)
Dim jsonValue = JsonConvert.SerializeXmlNode(doc)
Dim jsonObject = JObject.Parse(jsonValue)
Console.WriteLine(jsonObject("Person")("Name"))
dotnetfiddle demo
output :
foo

Accessing json object in vb.net after converting from XML

I convert XML to JSON like so:
Dim doc As XmlDocument
doc.LoadXml(arg_strXml)
Dim jsonObject As String = JsonConvert.SerializeXmlNode(doc)
Now I would like to be able to go into jsonObject to get values, like so
Dim mode As String = jsobObject.mode
Or more advanced example
Dim usersFirstName As String = jsonObject.people[1].firstname
Do I need to create a class which represents the XML structure or can I do it another way, even if I lose the intellisense, like so
Dim mode As String = jsonObject["mode"]
Seems like you first conversion was unnecessary,
you can access all values you need from xml with LINQ to XML and feature of vb.net XML Literals
Dim xmlString as String = "
<someobject>
<property1>Value 1</property1>
<property2>1001</property2>
</someobject>"
Dim xmlObject As XElement = XElement.Parse(xmlString)
Dim value1 As String = xmlObject.<property1>.First().Value
Dim value2 As String = xmlObject.<property2>.First().Value

DeserializeObject from JSON to a Dynamic Type

In VB.NET, is it possible to deserialize a JSON string to a dynamic / unknown datatype, then read the values from the object?
Dim js As New System.Web.Script.Serialization.JavaScriptSerializer()
Dim o As Object = js.DeserializeObject(json)
Dim s As String = String.Empty
For Each i As PropertyInfo In o.GetType().GetProperties()
s = String.Concat(s, i.Name) & "<br>"
Next
Response.Write(s)
It lists a bunch of things inside the object, but I can't seem to get to the value of these fields / properties.

Newtonsoft json exception

I am currently making a program that parses the Urban Dictionary API but I cannot get it to return the selected definition.
This is my current code fore retrieving and parsing the data:
Dim sourceString As String = New System.Net.WebClient().DownloadString("http://api.urbandictionary.com/v0/define?term=" & strRet)
rtxtDefinition.Text = sourceString
Dim jResults As JArray = JArray.Parse(sourceString)
Dim results As List(Of JToken) = jResults.Children().ToList()
For Each item As JProperty In results
item.CreateReader()
MsgBox(item.Value("definition"))
Next
note that strRet is the users input
this is an example of the urban dictionary API structure: http://pastebin.com/11Z5uVRN
The current code does not have support to find the (n)th definition only because I first need to get it to return a definition.
So obviously I am doing something wrong because of the error: Newtonsoft.Json.JsonReaderException but I am not sure.
Any help would be amazing. Thanks!
EDIT:
Root of json string you're dealing with is not an array but single object. Therefore, you can parse it to JObject instead of JArray, for example :
Dim jobj As JObject = JObject.Parse(sourceString);
Dim arr As JArray = jobj("list");
For Each(var item in arr.Children(Of JObject)())
MsgBox(item("definition").ToString());
Next

Parse Simple JSON with VB.NET

I have a simple JSON string that I am trying to parse with Visual Studio Express 2010 using native .net 4.0 instead of NewtonSoft. The json data that I am trying to parse looks like the following.
"{"token_type":"Bearer",""expires_in":3599,"access_token":"VxwK6YWYj6paqyMK2D2r4uDl34qg"}"
I can get the following code to run without error but when I try to dump the contents of the object I don't have any in the list. Here is the class I created.
Public Class AuthToken
Public Property token_type As String
Get
Return m_token_type
End Get
Set(ByVal value As String)
m_token_type = value
End Set
End Property
Private m_token_type As String
Public Property expires_in() As Integer
Get
Return m_expires_in
End Get
Set(ByVal value As Integer)
m_expires_in = value
End Set
End Property
Private m_expires_in As String
Public Property access_token As String
Get
Return m_access_token
End Get
Set(ByVal value As String)
m_access_token = value
End Set
End Property
Private m_access_token As String
End Class
My feeling is that my problem is in my class but I am not sure. So after looking for hours on this site and others Trouble parsing Json into .net Object I have put together the following code to parse the information and dump it to a RichTextBox just to see what it is.
Dim sr As New StreamReader(req.GetResponse.GetResponseStream)
Dim authtoken As New List(Of AuthToken)()
Dim ms As New MemoryStream(System.Text.Encoding.Unicode.GetBytes(sr.ReadToEnd))
Dim serializer As New System.Runtime.Serialization.Json.DataContractJsonSerializer(authtoken.GetType)
authtoken = DirectCast(serializer.ReadObject(ms), List(Of AuthToken))
ms.Close()
ms.Dispose()
sr.Close()
sr.Dispose()
For Each token In authtoken
rtbResponse.AppendText("Token: " & token.access_token & " Expires in: " & token.expires_in)
Next
So is my class created incorrectly? Is the data from the memorystream just not getting into the authtoken object because the class doesn't match the contents of the json data as it is deserialized?
If I am using the "DataContractSerializer" do I need to have data contract "stuff" in my class?
Any help is GREATLY appreciated.
The data is not getting into the authtoken variable because you don't have a list of auth tokens there - only one object. So if you get those JSON objects one at the time get rid of your lists and do it like that:
Dim sr As New StreamReader(req.GetResponse.GetResponseStream)
Dim authtoken As AuthToken
Dim ms As New MemoryStream(System.Text.Encoding.Unicode.GetBytes(sr.ReadToEnd))
Dim serializer As New System.Runtime.Serialization.Json.DataContractJsonSerializer(GetType(AuthToken))
authtoken = DirectCast(serializer.ReadObject(ms), AuthToken)
ms.Close()
ms.Dispose()
sr.Close()
sr.Dispose()
rtbResponse.AppendText("Token: " & authtoken.access_token & " Expires in: " & authtoken.expires_in)