Error trying to parse JSON

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.
keymacAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David FavorLinux/LXD/WordPress/Hosting SavantCommented:
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.
it_saigeDeveloperCommented:
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-

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
Regardless of whether the JSON was malformed, solutions were provided to your question.
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

keymacAuthor 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 FavorLinux/LXD/WordPress/Hosting SavantCommented:
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 FavorLinux/LXD/WordPress/Hosting SavantCommented:
Also, as it_saige said...

"Regardless of whether the JSON was malformed, solutions were provided to your question."
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.