-
Nov 17th, 2020, 11:45 AM
#1
Thread Starter
New Member
Json Deserialize to List of Class
Afternoon Everyone,
I have not been coding for a very long time and a little rusty and been asked to knock up a little export utility that gets data from an API applies some various filters then exports to excel. I can grab the data from the API and I can export to excel easily but what I need to be able to do is deserialize from JSON into a list (of CustomClass) which is where I am drawing a blank. I have tried to research online and I am either not finding what I need or I am to dumb to understand (latter very probable).
The difficulty is that there is a collection of items within the collection in the json.
Here is my class for holding the data:
Code:
Public Class Ticket
Public dt As DateTime
Public summary As String
Public issuetype As String
Public team As String
Public priority As Integer
Public path As String
Public caller As String
Public CIPFA_priority As String
Public person As String
Public details As String
Public messages As New List(Of message)
End Class
Public Class message
Public from As String
Public recip As String
Public body As String
Public DT As DateTime
Public id As String
End Class
Here is a sample of the JSON that I get:
Code:
{
"records": {
"record": [{
"date": "Mon Jun 04 2018 16:31:18 GMT+0100 (BST)",
"summary": "Passenger lift",
"issuetype": "contractor",
"team": "unassigned",
"priority": "3",
"path": "Ground Floor: Ext. Lift",
"caller": "Staff Name Removed",
"CIPFA_priority": "",
"person": "Staff Name Removed",
"details": "Please carry out investigate of Lift not working.",
"allmessages": {
"messages": {
"message": {
"msgSubject": "New Helpdesk issue (contractor) (H-ID:000000-C00000-T000000): Ground Floor: Ext. Lift: 'lift '",
"msgTo": "Staff Name Removed",
"msgFrom": "Staff Name Removed",
"msgBody": "You have a new Helpdesk issue (contractor): Ground Floor: Lift: 'lift '\n\nHelpdesk issue (contractor) details:\nPlease carry out investigate of Lift not working.\n\nNOTE: either sender and recipient were the same or an attempt to also send this message by email and/or SMS on (Mon Jun 04 2018 16:31:30 GMT+0100 (BST)) was NOT successful. Please check relevant email/phone number details!",
"msgDate": "Mon Jun 04 2018 16:31:20 GMT+0100 (BST)"
}
}
},
"id": "00000",
"status": "in progress"
} ]
}
}
Any help is much appreciated!
-
Nov 17th, 2020, 12:20 PM
#2
Re: Json Deserialize to List of Class
Which version of VS are you using and what are you targeting (Framework, Core, etc)? The reason I ask is because JSON is a particularly moving target, of late, so the best approach is going to depend on your situation.
My usual boring signature: Nothing
-
Nov 17th, 2020, 02:17 PM
#3
Re: Json Deserialize to List of Class
your Ticket class needs a property "allmessages" of type "messages"
then you need a type "messages" that is a List (Of message).
Wait... check that...
Code:
"allmessages": {
"messages": {
"message": {
"msgSubject": "New Helpdesk issue (contractor) (H-ID:000000-C00000-T000000): Ground Floor: Ext. Lift: 'lift '",
"msgTo": "Staff Name Removed",
"msgFrom": "Staff Name Removed",
"msgBody": "You have a new Helpdesk issue (contractor): Ground Floor: Lift: 'lift '\n\nHelpdesk issue (contractor) details:\nPlease carry out investigate of Lift not working.\n\nNOTE: either sender and recipient were the same or an attempt to also send this message by email and/or SMS on (Mon Jun 04 2018 16:31:30 GMT+0100 (BST)) was NOT successful. Please check relevant email/phone number details!",
"msgDate": "Mon Jun 04 2018 16:31:20 GMT+0100 (BST)"
}
}
},
There is nothing there that says messages or even allmessages is a collection... they are each a single object. And not even a collection of a singe object, but very straight up, an object, not a collection.
-tg
-
Nov 17th, 2020, 03:40 PM
#4
Thread Starter
New Member
Re: Json Deserialize to List of Class
Originally Posted by Shaggy Hiker
Which version of VS are you using and what are you targeting (Framework, Core, etc)? The reason I ask is because JSON is a particularly moving target, of late, so the best approach is going to depend on your situation.
2019 targeting .net Framework.
-
Nov 17th, 2020, 03:41 PM
#5
Thread Starter
New Member
Re: Json Deserialize to List of Class
Originally Posted by techgnome
your Ticket class needs a property "allmessages" of type "messages"
then you need a type "messages" that is a List (Of message).
Wait... check that...
Code:
"allmessages": {
"messages": {
"message": {
"msgSubject": "New Helpdesk issue (contractor) (H-ID:000000-C00000-T000000): Ground Floor: Ext. Lift: 'lift '",
"msgTo": "Staff Name Removed",
"msgFrom": "Staff Name Removed",
"msgBody": "You have a new Helpdesk issue (contractor): Ground Floor: Lift: 'lift '\n\nHelpdesk issue (contractor) details:\nPlease carry out investigate of Lift not working.\n\nNOTE: either sender and recipient were the same or an attempt to also send this message by email and/or SMS on (Mon Jun 04 2018 16:31:30 GMT+0100 (BST)) was NOT successful. Please check relevant email/phone number details!",
"msgDate": "Mon Jun 04 2018 16:31:20 GMT+0100 (BST)"
}
}
},
There is nothing there that says messages or even allmessages is a collection... they are each a single object. And not even a collection of a singe object, but very straight up, an object, not a collection.
-tg
It is a collection just that example only has one message but it can have multiple. I don't have an example on me right now but will dig one out with multiple messages.
-
Nov 17th, 2020, 03:46 PM
#6
Re: Json Deserialize to List of Class
Get better example with more data, copy to clipboard, in Visual Studio use Edit|Paste Special|Paste JSON As Classes and see the generated classes. They may need some fixes to get it working. You will see how much different are the generated ones from what you defined as Ticket and Message classes.
-
Nov 17th, 2020, 11:44 PM
#7
Re: Json Deserialize to List of Class
Originally Posted by MCRO
It is a collection just that example only has one message but it can have multiple. I don't have an example on me right now but will dig one out with multiple messages.
Do, becaue the current example doesn't indicate that it can be a collection... Even if there's only one, if it's intended to be part of a list/collection, it should be surrounded by square brackets.
-tg
-
Nov 18th, 2020, 10:41 AM
#8
Re: Json Deserialize to List of Class
Originally Posted by peterst
Get better example with more data, copy to clipboard, in Visual Studio use Edit|Paste Special|Paste JSON As Classes and see the generated classes. They may need some fixes to get it working. You will see how much different are the generated ones from what you defined as Ticket and Message classes.
I was not aware of this, I've been defining my classes by hand.
-
Nov 18th, 2020, 02:07 PM
#9
Re: Json Deserialize to List of Class
Try the following
Code:
Imports System.IO
'
' NuGet package below
'
Imports System.Text.Json
Public Class Form1
Private Sub DeserializeButton_Click(sender As Object, e As EventArgs) Handles DeserializeButton.Click
Dim fileName = "json.json"
Dim json = File.ReadAllText(fileName)
Dim results As RecordRoot = JsonSerializer.Deserialize(Of RecordRoot)(json)
End Sub
End Class
'
' Classes below to be in their own class files.
'
Public Class RecordRoot
Public Property records As Records
End Class
Public Class Records
Public Property record() As Record()
End Class
Public Class Record
Public Property _date As String
Public Property summary As String
Public Property issuetype As String
Public Property team As String
Public Property priority As String
Public Property path As String
Public Property caller As String
Public Property CIPFA_priority As String
Public Property person As String
Public Property details As String
Public Property allmessages As Allmessages
Public Property id As String
Public Property status As String
End Class
Public Class Allmessages
Public Property messages As Messages
End Class
Public Class Messages
Public Property message As Message
End Class
Public Class Message
Public Property msgSubject As String
Public Property msgTo As String
Public Property msgFrom As String
Public Property msgBody As String
Public Property msgDate As String
End Class
Attachment 179314
-
Nov 30th, 2020, 08:14 AM
#10
Thread Starter
New Member
Re: Json Deserialize to List of Class
Thank you for the great advice has taught me a couple of things which is really helpful such as pasting as class! Never knew that.
I am having a little bit of an issue though. So I took my entire JSON output (over 18,000 lines) and pasted as class. I then took the the deserializer line of code which is where it errors:
Code:
Dim results As Rootobject = JsonSerializer.Deserialize(Of Rootobject)(json)
The error is:
System.Text.Json.JsonException: 'The JSON value could not be converted to Flow_360_API.Record. Path: $.record | LineNumber: 1 | BytePositionInLine: 12.'
This exception was originally thrown at this call stack:
[External Code]
Flow_360_API.Flow360API.ActiveIssuesSummary(String) in Flow360API.vb
Flow360_Exporter.Form1.Button1_Click(Object, System.EventArgs) in Form1.vb
[External Code]
The code is as follows:
Code:
Public Function ActiveIssuesSummary(Optional Team As String = Nothing) As Rootobject
Dim json As String = webClient.DownloadString("https://url.here/request/?info1=info")
json = json.Substring(11, json.Length - (12))
Dim results As Rootobject = JsonSerializer.Deserialize(Of Rootobject)(json)
Return results
End Function
The reason for the substring is the json that gets returned fails json validator online as it has some extran bumf at the start and end so I cam just removing that but passes as valid json post cleanup.
Here are the classes generated:
Code:
Public Class Rootobject
Public Property record() As Record
End Class
Public Class Record
Public Property _date As String
Public Property summary As String
Public Property issuetype As String
Public Property team As String
Public Property priority As String
Public Property path As String
Public Property caller As String
Public Property CIPFA_priority As String
Public Property person As String
Public Property details As String
Public Property allmessages As Allmessages
Public Property id As String
Public Property status As String
End Class
Public Class Allmessages
Public Property messages As Messages
End Class
Public Class Messages
Public Property message As Object
End Class
and finally here is a subset of the information in the json request and it fails if I manually pass just this subset through with the same error:
Code:
{
"record": [{
"date": "Fri Nov 27 2020 12:40:00 GMT-0000 (GMT)",
"summary": "IT: Monday period 3 and 4",
"issuetype": "ICT Service",
"team": "IT Support",
"priority": "",
"path": "123",
"caller": "123",
"CIPFA_priority": "",
"person": "unassigned",
"details": "123",
"allmessages": {
"messages": {
"message": {
"msgSubject": "123",
"msgTo": "123",
"msgFrom": "123",
"msgBody": "123",
"msgDate": "Fri Nov 27 2020 12:40:00 GMT-0000 (GMT)"
}
}
},
"id": "123",
"status": "open"
}, {
"date": "Fri Nov 27 2020 14:18:56 GMT-0000 (GMT)",
"summary": "Projector for installation film",
"issuetype": "ICT service",
"team": "IT Support",
"priority": "",
"path": "123",
"caller": "123",
"CIPFA_priority": "",
"person": "unassigned",
"details": "123",
"allmessages": {
"messages": {
"message": [{
"msgSubject": "123",
"msgTo": "123",
"msgFrom": "123",
"msgBody": "123",
"msgDate": "Fri Nov 27 2020 14:18:58 GMT-0000 (GMT)"
}, {
"msgSubject": "123",
"msgTo": "123",
"msgFrom": "123",
"msgBody": "123",
"msgDate": "Fri Nov 27 2020 14:18:58 GMT-0000 (GMT)"
}]
}
},
"id": "1372376",
"status": "open"
}]
}
123 values have been replaced due to confidential informaiton
Last edited by MCRO; Nov 30th, 2020 at 08:33 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|