I have this nested structure
and want to parse it into classes.
I have this code to get the json file and to deserialize it
Public Function getDatasources(ByVal _token As String) As List(Of Results)
Dim client = New RestClient(_baseURI)
Dim request = New RestRequest("/datasource", Method.GET)
request.AddHeader("Authorization", "Bearer " + _token)
request.AddHeader("environment", _environment)
Dim jstr = client.Execute(request).Content
Dim datasourceInfo As List(Of Results) = JsonConvert.DeserializeObject(Of List(Of Results))(jstr)
Return datasourceInfo
End Function
And build this class structure
Public Class Results
Public Property results As List(Of DatasourceInfos)
End Class
Public Class DatasourceInfos
Public Property DSContainer() As List(Of DatasourceInfo)
End Class
Public Class DatasourceInfo
Public Property id As String
Public Property name As String
Public Property description As String
Public Property created As ULong
Public Property modified As ULong
Public Property creator As List(Of Creator)
Public Property editor As List(Of Editor)
End Class
Public Class Creator
Public Property email As String
Public Property login As String
End Class
Public Class Editor
Public Property email As String
Public Property login As String
End Class
But running the code the object datasourceInfo is empty and I do not know why. Anyone who can help me here?
You've mistaken the meaning of the JSON icons. Only square brackets [] denote arrays/lists. The curly brackets {} denote objects.
results is a list of DatasourceInfo (not a list of a list).
DatasourceInfo.creator is a single Creator, and:
DatasourceInfo.editor is a single Editor.
Your code should be changed to:
Public Class Results
Public Property results As List(Of DatasourceInfo)
End Class
Public Class DatasourceInfo
...your other properties...
Public Property creator As Creator
Public Property editor As Editor
End Class
The DatasourceInfos class (note the s on the end) can be removed altogether.
Related
I'm trying to access Googles book api and just populate textboxes with the information.
Here's an example of the API json: [https://www.googleapis.com/books/v1/volumes?q=isbn:9780979799006]
I used Visual Studio's Paste Special to create the Class. Here it is:
Public Class GoogleBookData
Public Class Rootobject
Public Property kind As String
Public Property totalItems As Integer
Public Property items() As Item
End Class
Public Class Item
Public Property kind As String
Public Property id As String
Public Property etag As String
Public Property selfLink As String
Public Property volumeInfo As Volumeinfo
Public Property saleInfo As Saleinfo
Public Property accessInfo As Accessinfo
Public Property searchInfo As Searchinfo
End Class
Public Class Volumeinfo
Public Property title As String
Public Property subtitle As String
Public Property publishedDate As String
Public Property description As String
Public Property industryIdentifiers() As Industryidentifier
Public Property readingModes As Readingmodes
Public Property pageCount As Integer
Public Property printType As String
Public Property categories() As String
Public Property maturityRating As String
Public Property allowAnonLogging As Boolean
Public Property contentVersion As String
Public Property panelizationSummary As Panelizationsummary
Public Property imageLinks As Imagelinks
Public Property language As String
Public Property previewLink As String
Public Property infoLink As String
Public Property canonicalVolumeLink As String
End Class
Public Class Readingmodes
Public Property text As Boolean
Public Property image As Boolean
End Class
Public Class Panelizationsummary
Public Property containsEpubBubbles As Boolean
Public Property containsImageBubbles As Boolean
End Class
Public Class Imagelinks
Public Property smallThumbnail As String
Public Property thumbnail As String
End Class
Public Class Industryidentifier
Public Property type As String
Public Property identifier As String
End Class
Public Class Saleinfo
Public Property country As String
Public Property saleability As String
Public Property isEbook As Boolean
End Class
Public Class Accessinfo
Public Property country As String
Public Property viewability As String
Public Property embeddable As Boolean
Public Property publicDomain As Boolean
Public Property textToSpeechPermission As String
Public Property epub As Epub
Public Property pdf As Pdf
Public Property webReaderLink As String
Public Property accessViewStatus As String
Public Property quoteSharingAllowed As Boolean
End Class
Public Class Epub
Public Property isAvailable As Boolean
End Class
Public Class Pdf
Public Property isAvailable As Boolean
End Class
Public Class Searchinfo
Public Property textSnippet As String
End Class
End Class
I call this function to read the stream and get the Class data:
Public Shared Function getGoogleBookData(ByVal sSku As String) As GoogleBookData
Dim result As String = Nothing
Dim url As String = "https://www.googleapis.com/books/v1/volumes?q=isbn:"
url &= sSku
Dim request As HttpWebRequest = WebRequest.Create(url)
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader = Nothing
Dim myJson As String = Nothing
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
myJson = reader.ReadToEnd
Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
Dim myGBookData As New GoogleBookData
myGBookData = serializer.Deserialize(Of GoogleBookData)(myJson)
Return myGBookData
End Function
I call the function:
Dim gsSearchSku as String = "9780979799006"
Dim myGItem As New GoogleBookData
myGItem = getGoogleBookData(gsSearchSku)
Then, I've tried several things to try to access any data in the Class:
I know this doesn't work but put it here so you can get an idea of what I'm trying.
Dim sTitle as String = myGItem.Item.Title
I can't even run it. GoogleBookData.item is a class type and cannot be used as an expression.
No idea where to go from here.
Any help would be greatly appreciated!!
My class is not being populated with the JSON string
Using the VS 2012 Edit -> Paste Special -> JSON as a CLASS
The Class Created:
Public Class clsMCParcelData
Public Class Rootobject
Public Property ParcelFound As Boolean
Public Property ParcelInfo As New APN
End Class
Public Class APN
Public Property Book As String
Public Property Map As String
Public Property Item As String
Public Property clean As String
Public Property formatted As String
Public Property link As String
End Class
END CLASS
JSON String:
{
"ParcelFound":true,
"APN":{
"Book":"510",
"Map":"11",
"Item":"668",
"clean":"51011668",
"formatted":"510-11-668",
"link":"\/api\/parcel\/51011668"
}
}
Code on the asp.vb page:
Dim jss As New JavaScriptSerializer, MCD As New clsMCParcelData.Rootobject
MCD = jss.Deserialize(Of clsMCParcelData.Rootobject)(raw)
I would expect that once deserialized, I would be able to access the APN information like so:
tbParcelNumber.text = MCD.ParcelInfo.formatted (returning 510-11-668)
What I get is Nothing as the value of MCD.ParcelInfo.formatted
The JavaScriptSerializer requires an exact match in the class to deserialize.
I have this JSON data that I would like to parse but I'm not sure how to go about it.
Here's the JSON:
{
"input":{
"lat":32.761125,
"lon":-96.791339
},
"results":[
{
"block_fips":"481130204001105",
"bbox":[
-96.79587,
32.753273,
-96.787714,
32.76218
],
"county_fips":"48113",
"county_name":"Dallas",
"state_fips":"48",
"state_code":"TX",
"state_name":"Texas",
"block_pop_2015":2,
"amt":"AMT004",
"bea":"BEA127",
"bta":"BTA101",
"cma":"CMA009",
"eag":"EAG005",
"ivm":"IVM009",
"mea":"MEA032",
"mta":"MTA007",
"pea":"PEA008",
"rea":"REA005",
"rpc":"RPC004",
"vpc":"VPC004"
}
]
}
I used the Visual Studio tool, Edit -> Paste Special -> Paste as JSON classes, to convert this JSON in classes and it gave me this class structure:
Public Class Rootobject
Public Property input As Input
Public Property results() As Result
End Class
Public Class Input
Public Property lat As Single
Public Property lon As Single
End Class
Public Class Result
Public Property block_fips As String
Public Property bbox() As Single
Public Property county_fips As String
Public Property county_name As String
Public Property state_fips As String
Public Property state_code As String
Public Property state_name As String
Public Property block_pop_2015 As Integer
Public Property amt As String
Public Property bea As String
Public Property bta As String
Public Property cma As String
Public Property eag As String
Public Property ivm As String
Public Property mea As String
Public Property mta As String
Public Property pea As String
Public Property rea As String
Public Property rpc As String
Public Property vpc As String
End Class
So then what I did to try and parse the data is:
Dim MyJSON As String = JsonAbove
Dim jss As New JavaScriptSerializer()
Dim dict = jss.Deserialize(Of Result)(rawresp)
MsgBox(dict.state_name)
All I get is a blank MessageBox with no results.
Am I doing something wrong?
Use List Of Objects instead of array in your class. I have done two changes One in the rootobject for results and other in the result class for bbox
Public Class Rootobject
Public Property input As Input
Public Property results As List(Of Result)
End Class
Public Class Input
Public Property lat As Single
Public Property lon As Single
End Class
Public Class Result
Public Property block_fips As String
Public Property bbox As List(Of Single)
Public Property county_fips As String
Public Property county_name As String
Public Property state_fips As String
Public Property state_code As String
Public Property state_name As String
Public Property block_pop_2015 As Integer
Public Property amt As String
Public Property bea As String
Public Property bta As String
Public Property cma As String
Public Property eag As String
Public Property ivm As String
Public Property mea As String
Public Property mta As String
Public Property pea As String
Public Property rea As String
Public Property rpc As String
Public Property vpc As String
End Class
Then access the properties
Dim jss As New JavaScriptSerializer()
Dim dict = jss.Deserialize(Of Rootobject)(MyJSON)
MsgBox(dict.results.FirstOrDefault().state_name)
Same, using the Newtonsoft.Json namespace.
The classes properties have being assigned new names, using a <JsonProperty> attribute.
Also, the Results property is modified to return a List(Of Result).
The deserialization is pretty simple and straightforward:
You can use the Visual Studio NuGet Package Manager to install Newtonsoft.Json.
Imports Newtonsoft.Json
Dim latlonResults As RootObject = JsonConvert.DeserializeObject(Of RootObject)(JSON)
Dim state As String = latlonResults.Results(0).StateName
or access a property directly while deserializing:
Dim state As String = JsonConvert.DeserializeObject(Of RootObject)(JSON).Results(0).StateName
Refactored classes:
Public Class RootObject
<JsonProperty("input")>
Public Property Input() As Input
<JsonProperty("results")>
Public Property Results() As List(Of Result)
End Class
Public Class Input
<JsonProperty("lat")>
Public Property Lat() As Double
<JsonProperty("lon")>
Public Property Lon() As Double
End Class
Public Class Result
<JsonProperty("block_fips")>
Public Property BlockFips() As String
<JsonProperty("bbox")>
Public Property Bbox() As List(Of Double)
<JsonProperty("county_fips")>
Public Property CountyFips() As Long
<JsonProperty("county_name")>
Public Property CountyName() As String
<JsonProperty("state_fips")>
Public Property StateFips() As Long
<JsonProperty("state_code")>
Public Property StateCode() As String
<JsonProperty("state_name")>
Public Property StateName() As String
<JsonProperty("block_pop_2015")>
Public Property BlockPop2015() As Long
<JsonProperty("amt")>
Public Property Amt() As String
<JsonProperty("bea")>
Public Property Bea() As String
<JsonProperty("bta")>
Public Property Bta() As String
<JsonProperty("cma")>
Public Property Cma() As String
<JsonProperty("eag")>
Public Property Eag() As String
<JsonProperty("ivm")>
Public Property Ivm() As String
<JsonProperty("mea")>
Public Property Mea() As String
<JsonProperty("mta")>
Public Property Mta() As String
<JsonProperty("pea")>
Public Property Pea() As String
<JsonProperty("rea")>
Public Property Rea() As String
<JsonProperty("rpc")>
Public Property Rpc() As String
<JsonProperty("vpc")>
Public Property Vpc() As String
End Class
I have a self referencing loop. I tried reading and implementing some of the other answers but it does not seem to work. I have a class that saves my object as a json file (method). It attempts to serialize the object but throws an exception for a self-referencing loop. The object I am serializing is the second block (class). How can I fix the issue? It did work until I added buttons, so I am assuming I am doing something wrong with handlers, but I really have no idea.
Public Sub saveLocalSettings()
Console.WriteLine("saveLocalSettings")
If Not Directory.Exists(_SettingsFile) Then
Directory.CreateDirectory(_SettingsFile)
End If
' Try
Dim strConfigurationManager As String = JsonConvert.SerializeObject(_LocalSettings, PreserveReferencesHandling.Objects)
'Dim strConfigurationManager As String = JsonConvert.SerializeObject(_LocalSettings, Newtonsoft.Json.ReferenceLoopHandling.Ignore)
lm.writeFile(_SettingsFile + _FileName, strConfigurationManager, True)
' Catch ex As Exception
' End Try
End Sub
Imports Newtonsoft.Json
Public Class RGOSetting
Public Property id As String
Public Property title As String
Private mtbTitle As New MaskedTextBox
Public Property sharestatus As Integer
Public Property settingstring As String
Public Property userid As Integer
Public Property setting_profiles As New List(Of RGOSettingProfile)
Private rgolcm As RGOLeagueChampionManager
' Private rgolssm As RGOLeagueSumSpManager
Public btnUpdate As New Button
Public btnReset As New Button
Public btnClear As New Button
End Class
Public Class RGOSettingProfile
Public Property champion As LeagueChampion
Public Property summoner_spells As New List(Of LeagueSummonerSpell)
Public Sub New()
End Sub
Public Sub New(ByVal strChampion As String, ByVal strSummonerSpell As List(Of String))
End Sub
End Class
I ended up doing this with the buttons and it allowed me to save the objects:
<JsonIgnore> Public btnUpdate As New Button
<JsonIgnore> Public btnReset As New Button
<JsonIgnore> Public btnClear As New Button
I can't figure it out why ALL fields return null. My classes seem correct and fit the json perfectly. I used the JSON Util tool to convert my JSON result to VB (http://jsonutils.com/). I tried the project in C# but end up resulting the same problem. I'm using RestSharp to make my request and JSON.NET to deserialize my object.
Note that the RestSharp content is not empty and is equal to the JSON i added below.
Here is the Json :
{"customer":{"created_at":"2015-10-10T16:35:07-04:00","cust_identifier":null,"description":null,"domains":null,"id":8000039822,"name":"ACTION VEHICULES D'OCCASION","note":null,"sla_policy_id":8000012148,"updated_at":"2015-10-15T09:43:09-04:00","custom_field":{"cf_etat_client":"NO","cf_dealer_code":"U4504033884","cf_manufacturer":"Used","cf_email":null,"cf_province":"QU\u00c9BEC","cf_region":null,"cf_address":"1913 CH CHAMBLY","cf_city":"CARIGNAN","cf_postal_code":null,"cf_phone_":"450 403-3884","cf_fax":null,"cf_tollfree":null,"cf_legal_name":"ACTION VEHICULES D'OCCASION","cf_dealer_princ":null,"cf_g_manager":null,"cf_cfo_finance":null,"cf_sales_manager":null,"cf_trade_resp":null,"cf_used_veh_manager":null,"cf_business_manager_1":null,"cf_business_manager_2":null,"cf_email_g_manager":null,"cf_email_gs_manager":null,"cf_email_s_manager":null,"cf_email_trade":null,"cf_fleet_lease":null,"cf_accounting":null,"cf_installed":null,"cf_demo":null,"cf_update":null,"cf_sold":null,"cf_dealer_website":null,"cf_i_t_contact":null,"cf_server_name":null,"cf_network":null,"cf_is_domain":null,"cf_easybackup":null,"cf_password":null,"cf_pc_installed":null,"cf_reference_by":null,"cf_error_":null,"cf_license_":null,"cf_is_amvoq":true}}}
Here both of my class i used to deserialize :
Public Class Customer
Public Property created_at As DateTime
Public Property cust_identifier As Object
Public Property description As Object
Public Property domains As Object
Public Property id As Long
Public Property name As String
Public Property note As Object
Public Property sla_policy_id As Long
Public Property updated_at As DateTime
Public Property custom_field As CustomField
End Class
Public Class CustomField
Public Property cf_etat_client As String
Public Property cf_dealer_code As String
Public Property cf_manufacturer As String
Public Property cf_email As Object
Public Property cf_province As String
Public Property cf_region As Object
Public Property cf_address As String
Public Property cf_city As String
Public Property cf_postal_code As Object
Public Property cf_phone_ As String
Public Property cf_fax As Object
Public Property cf_tollfree As Object
Public Property cf_legal_name As String
Public Property cf_dealer_princ As Object
Public Property cf_g_manager As Object
Public Property cf_cfo_finance As Object
Public Property cf_sales_manager As Object
Public Property cf_trade_resp As Object
Public Property cf_used_veh_manager As Object
Public Property cf_business_manager_1 As Object
Public Property cf_business_manager_2 As Object
Public Property cf_email_g_manager As Object
Public Property cf_email_gs_manager As Object
Public Property cf_email_s_manager As Object
Public Property cf_email_trade As Object
Public Property cf_fleet_lease As Object
Public Property cf_accounting As Object
Public Property cf_installed As Object
Public Property cf_demo As Object
Public Property cf_update As Object
Public Property cf_sold As Object
Public Property cf_dealer_website As Object
Public Property cf_i_t_contact As Object
Public Property cf_server_name As Object
Public Property cf_network As Object
Public Property cf_is_domain As Object
Public Property cf_easybackup As Object
Public Property cf_password As Object
Public Property cf_pc_installed As Object
Public Property cf_reference_by As Object
Public Property cf_error_ As Object
Public Property cf_license_ As Object
Public Property cf_is_amvoq As Boolean
End Class
Here is the Deserialize Function :
Public Shared Function JSONDeserializeFreshDeskCie(repContent As Stream) As Customer
Dim rs As Customer = Nothing
Dim test As Object
Dim serializer As New JsonSerializer()
Try
Using sr As New StreamReader(repContent)
Using jsonTextReader As New JsonTextReader(sr)
rs = serializer.Deserialize(Of Customer)(jsonTextReader)
End Using
End Using
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
Return rs
End Function
Here where i call my function to retrieve my object :
Private Sub loadAllCie(ByVal e As IRestResponse)
Dim rep As Stream = Nothing
Dim rs As Customer
Try
rep = New MemoryStream(e.RawBytes())
If e.ErrorException IsNot Nothing OrElse e.StatusCode <> Net.HttpStatusCode.OK Then
Dim strError As String = ""
If e.ErrorException IsNot Nothing Then
strError = "Error : " & e.ErrorException.Message & vbCrLf
End If
strError &= "Web Error : " & e.ErrorMessage
strError &= vbCrLf & e.StatusCode.ToString()
MessageBox.Show(strError)
Exit Try
End If
rs = JSONSerialization.JSONDeserializeFreshDeskCie(rep)
Dim allo As String = ""
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
If rep IsNot Nothing Then
rep.Close()
End If
End Try
End Sub
Look at the start of the JSON:
{"customer":{"created_at"...
There is an outer container created to hold "customer" which your code does not account for. If you do not want to create a do-nothing class for it, parse the result first:
Dim jstr = ...from whereever
Dim jobj = JObject.Parse(jstr)
Dim cust = JsonConvert.DeserializeObject(Of Customer)(jobj("customer").ToString)
To use a class:
Public Class CustContainer
Public Property customer As Customer
End Class
...
Dim cust = JsonConvert.DeserializeObject(Of CustContainer)(jstr)
I dont like the second because it requires all the rest of the references to be cust.customer.Foo, so I prefer to discard them.