Error trying to parse JSON

keymac
keymac used Ask the Experts™
on
I Have this JSON
[{"uuid":"ead6b1c6-700c-446b-a96d-4809a00ba119","name":"BECCOFINO","created_at":"2017-05-08 09:26:07","updated_at":"2018-09-18 15:35:10","deleted_at":null,"levels":{"level2":[{"type":"F&B","uuid":"d7dc52f6-8b94-4ae2-9d7e-9e72b1f03853","name":"Beccofino","created_at":"2018-09-18 15:33:58",      "updated_at":"2018-09-18 15:42:21","deleted_at":"2018-09-18 15:42:21","customer_uuid":"ead6b1c6-700c-446b-a96d-4809a00ba119"},{"type":"Con_tact","uuid":"f7c4c881-88cb-433c-9bd7-9057fe8239d3","name":"Andrea Rotolli","created_at":"2018-09-18 15:38:08","updated_at":"2018-09-18 15:42:08","deleted_at":"2018-09-18 15:42:08","surname":"Rotolli","forename":"Andrea",      "prop_Gender":"Male","prop_Seize":"UXXXL","customer_uuid":"ead6b1c6-700c-446b-a96d-4809a00ba119"}]},"categories":["Auto Return","Available in Track"],"sync":"customer"}]

with these classes
    Public Class cls_JSON_Levels_Header_New
        Public uuid As String
        Public name As String
        Public created_at As String
        Public updated_at As String
        Public deleted_at As String
        Public levels() As cls_JSON_Levels_Body
        Public categories() As String
        Public sync As String
    End Class

    Public Class cls_JSON_Levels_Body
        Public level2() As cls_JSON_Level_Details
        Public level3() As cls_JSON_Level_Details
    End Class

    Public Class cls_JSON_Level_Details
        Public type As String
        Public uuid As String
        Public name As String
        Public created_at As String
        Public updated_at As String
        Public deleted_at As String
        Public surname As String
        Public forename As String
        Public prop_gender As String
        Public prop_seize As String
        Public customer_uuid As String
    End Class

But get this error when parsing with

 JsonConvert.DeserializeObject(Of List(Of cls_JSON_Levels_Header_New))(strJSON)

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'WindowsApplication1.ConnectProcessing+cls_JSON_Levels_Body[]' 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<T>) 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 '[4].levels.level2', line 1, position 1181.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
David FavorFractional CTO
Distinguished Expert 2018

Commented:
Your JSON is valid data. That's good. Most problems relate to malformed JSON.

Your approach anticipates your JSON will always be well formed. Likely a bad assumption.

Better to just deserialize/decode JSON into an object + then pick out fields + when a mandatory field is missing raise an exception.

This way you'll have far more detail about either JSON data breakage or code breakage.

Your approach is a go/nogo, so you only have success or failure, with no detail about failure reasons, when they occur.

Try changing your logic to produces highly granular debug diagnostics, then roll this all into an object constructor.
Commented:
Try this:
Imports System.Reflection
Imports System.Runtime.CompilerServices

Module Module1
	ReadOnly json As String = "[{
			'uuid':'ead6b1c6-700c-446b-a96d-4809a00ba119',
			'name':'BECCOFINO',
			'created_at':'2017-05-08 09:26:07',
			'updated_at':'2018-09-18 15:35:10',
			'deleted_at':null,
			'levels':{
				'level2':[{
					'type':'F&B',
					'uuid':'d7dc52f6-8b94-4ae2-9d7e-9e72b1f03853',
					'name':'Beccofino',
					'created_at':'2018-09-18 15:33:58',
					'updated_at':'2018-09-18 15:42:21',
					'deleted_at':'2018-09-18 15:42:21',
					'customer_uuid':
					'ead6b1c6-700c-446b-a96d-4809a00ba119'
				},{
					'type':'Con_tact',
					'uuid':'f7c4c881-88cb-433c-9bd7-9057fe8239d3',
					'name':'Andrea Rotolli',
					'created_at':'2018-09-18 15:38:08',
					'updated_at':'2018-09-18 15:42:08',
					'deleted_at':'2018-09-18 15:42:08',
					'surname':'Rotolli',
					'forename':'Andrea',
					'prop_Gender':'Male',
					'prop_Seize':'UXXXL',
					'customer_uuid':'ead6b1c6-700c-446b-a96d-4809a00ba119'
				}
			]},
			'categories':[
				'Auto Return',
				'Available in Track'
			],
			'sync':'customer'
		}]"

	Sub Main()
		Dim converted As cls_JSON_Levels_Header() = Newtonsoft.Json.JsonConvert.DeserializeObject(Of cls_JSON_Levels_Header())(json)
		For Each header As cls_JSON_Levels_Header In converted
			Console.WriteLine(header)
		Next
		Console.ReadLine()
	End Sub

End Module

Class cls_JSON_Levels_Header
	Public Property uuid() As Nullable(Of Guid)
	Public Property name() As String
	Public Property created_at() As Nullable(Of DateTime)
	Public Property updated_at() As Nullable(Of DateTime)
	Public Property deleted_at() As Nullable(Of DateTime)
	Public Property levels() As cls_JSON_Levels_Body
	Public Property categories() As String()
	Public Property sync() As String

	Public Overrides Function ToString() As String
		Return $"{{ {String.Join(", ", From prop In Me.GetType().GetProperties() Select $"{prop.Name}: {prop.GetValueOrValues(Me)}")} }}"
	End Function
End Class

Class cls_JSON_Levels_Body
	Public Property level2() As cls_JSON_Level_Details()

	Public Overrides Function ToString() As String
		Return $"{{ {String.Join(", ", From prop In Me.GetType().GetProperties() Select $"{prop.Name}: {prop.GetValueOrValues(Me)}")} }}"
	End Function
End Class

Class cls_JSON_Level_Details
	Public Property type() As String
	Public Property uuid() As Nullable(Of Guid)
	Public Property name() As String
	Public Property created_at() As Nullable(Of DateTime)
	Public Property updated_at() As Nullable(Of DateTime)
	Public Property deleted_at() As Nullable(Of DateTime)
	Public Property surname() As String
	Public Property forename() As String
	Public Property prop_gender() As String
	Public Property prop_seize() As String
	Public Property customer_uuid() As Nullable(Of Guid)

	Public Overrides Function ToString() As String
		Return $"{{ {String.Join(", ", From prop In Me.GetType().GetProperties() Select $"{prop.Name}: {prop.GetValueOrValues(Me)}")} }}"
	End Function
End Class

Module Extensions
	<Extension>
	Public Function GetValueOrValues([property] As PropertyInfo, source As Object) As String
		Dim value As Object = [property].GetValue(source, Nothing)
		If value Is Nothing Then
			Return String.Empty
		ElseIf Not [property].PropertyType = GetType(String) AndAlso GetType(IEnumerable).IsAssignableFrom([property].PropertyType) Then
			Return $"{{ {String.Join(", ", From item In CType(value, IEnumerable(Of Object)) Select item)} }}"
		Else
			Return value.ToString()
		End If
	End Function
End Module

Open in new window

Which produces the following output -Capture.PNG-saige-

Commented:
Regardless of whether the JSON was malformed, solutions were provided to your question.
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Author

Commented:
Apologies but the JSON was malformed as the block that was giving error was essentially an object rather than an array and the provider reformatted the JSON to make it properly parse
David FavorFractional CTO
Distinguished Expert 2018

Commented:
Well... If your JSON parser was throwing an error, then you best find another parser, as the JSON you provided was correct/parseable... even though it might have been a different format than what you imagined.

Tip: Whenever you'd like to convert JSON to human readable format, run your JSON through the https://jsonformatter.org/ + you'll instantly know if the JSON is correct/invalid + you'll also see the exact data structure produced from the parse.
David FavorFractional CTO
Distinguished Expert 2018

Commented:
Also, as it_saige said...

"Regardless of whether the JSON was malformed, solutions were provided to your question."

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial