Here is a Converter Helper class (converted from C#) used in commercial applications. It will convert to/From POCOs <-> JSON.
Imports Newtonsoft.Json
Public Class JsonConverter
Public Shared Function FromClass(Of T)(data As T, Optional isEmptyToNull As Boolean = False, Optional jsonSettings As JsonSerializerSettings = Nothing) As String
Dim response As String = String.Empty
If (data IsNot Nothing) Then
Try
response = JsonConvert.SerializeObject(data, jsonSettings)
Catch ex As Exception
Debug.WriteLine(ex)
Throw
End Try
End If
Return If(isEmptyToNull, (If(response = "{}", "null", response)), response)
End Function
Public Shared Function ToClass(Of T)(data As String, Optional jsonSettings As JsonSerializerSettings = Nothing) As T
Dim response As T = Nothing
If Not String.IsNullOrEmpty(data) Then
Try
response = If(jsonSettings Is Nothing, JsonConvert.DeserializeObject(Of T)(data), JsonConvert.DeserializeObject(Of T)(data, jsonSettings))
Catch ex As Exception
Debug.WriteLine(ex)
Throw
End Try
End If
Return response
End Function
End Class
To Use it:
Dim raw As New Data() With
{
.Codice = "Field 1",
.Descrizione = "Field 2",
.Composizione = "Field 3",
.CodCategoria = "Field 4"
}
Dim json As String = JsonConverter.FromClass(raw)
Dim raw2 = JsonConverter.ToClass(Of Data)(json)
UPDATE
I must admit, I did not look closely at the JSON data until I looked at Richard's Solution.
So the following update uses the above
JsonConverter
helper class but also maintains the class structure that you want. The only thing that you need to do is add the custom
ResultDataConverter
attribute to the
Result
class.
Imports System.IO
Imports Newtonsoft.Json.Linq
Imports Json = Newtonsoft.Json
Module Module1
Sub Main()
Dim filePath As String = Path.Combine("FilePath", "FileName")
Dim data As String = FileHelper.TextRead(filePath)
Dim result = JsonConverter.ToClass(Of Result)(data)
Debugger.Break()
End Sub
End Module
<Json.JsonConverter(GetType(ResultDataConverter))>
Public Class Result
Public Property Data() As List(Of Data)
End Class
Public Class Data
Public Property CODICE() As String
Public Property DESCRIZIONE() As String
Public Property COMPOSIZIONE() As String
Public Property CODCATEGORIA() As String
Public Property PREZZO() As Single
Public Property PREZZOPROMO() As Single
Public Property SCONTOPROMO() As Single
Public Property PROMODADATA() As Date
Public Property PROMOADATA() As Date
Public Property CODMODELLO() As String
Public Property DESCRIZIONEBREVEWEB() As String
End Class
Public Class ResultDataConverter
Inherits Json.JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return True
End Function
Public Overrides Function ReadJson(reader As Json.JsonReader, objectType As Type, existingValue As Object, serializer As Json.JsonSerializer) As Object
Dim obj As Result = Nothing
If reader.TokenType = Json.JsonToken.StartObject Then
Dim jObject As JObject = JObject.Load(reader)
If jObject IsNot Nothing AndAlso jObject.HasValues Then
Dim result = jObject("result")
If result IsNot Nothing Then
obj = New Result()
Dim root = serializer.Deserialize(Of IList(Of JObject))(result.CreateReader())
Dim jMeta = root.First().Children().Where(Function(x) x.Path = "meta")
Dim jData = root.First().Children().Where(Function(x) x.Path = "data")
Dim lookup = jMeta.Children() _
.Children() _
.Select(Function(x) x.First.ToString()) _
.Select(Function(x, i) New With {.x = x, .i = i}) _
.ToDictionary(Function(x) x.x, Function(x) x.i)
Dim dataElements = jData.Children().Children().ToList()
obj.Data = New List(Of Data)()
For i As Integer = 0 To dataElements.Count - 1
Dim element = New Data()
If lookup.Keys.Contains("CODICE") Then
element.CODICE = dataElements(i)(lookup("CODICE")).ToString()
End If
If lookup.Keys.Contains("DESCRIZIONE") Then
element.DESCRIZIONE = dataElements(i)(lookup("DESCRIZIONE")).ToString()
End If
obj.Data.Add(element)
Next
End If
End If
End If
Return obj
End Function
Public Overrides Sub WriteJson(writer As Json.JsonWriter, value As Object, serializer As Json.JsonSerializer)
Throw New NotImplementedException()
End Sub
End Class
Public Class FileHelper
Public Shared Function TextRead(fileName As String) As String
Return TextRead(Path.GetFileName(fileName), Path.GetDirectoryName(fileName))
End Function
Public Shared Function TextRead(fileName As String, filePath As String) As String
Dim data As String = String.Empty
Dim myFile As String = Path.Combine(filePath, fileName)
If Directory.Exists(filePath) AndAlso File.Exists(myFile) Then
Using reader = New StreamReader(myFile)
data = reader.ReadToEnd()
End Using
End If
Return data
End Function
End Class
By encapsulating the property mapping in a custom converter, this will make it easier in future to update if the JSON meta fields change. Simply update the Data class properties, then adjust the mappings in the custom converter.
Note: The custom
ResultDataConverter
is incomplete. You will need to add the other properties where I left a comment and bullet-proof the conversion if there is incomplete JSON data.