I’m using the JSON format for files used in one of my apps, and although Xojo.Data.GenerateJSON is able to properly create the Text from the Dictionary, it is unable to parse the JSON it creates and return my dictionary. The relevant code from my app is:
This is where the JSON text representation is created and saved:
dim json as new xojo.Core.Dictionary
json.Value(“loginID”) = loginID
json.Value(“Name”) = Name
json.Value(“TeamNumber”) = TeamNumber
json.Value(“Section”) = Section
json.Value(“Time”) = Time
dim json2() as xojo.Core.Dictionary
dim tmp as xojo.Core.Dictionary
for i as Integer = 0 to 2
tmp = new xojo.core.Dictionary
tmp.Value(“Name”) = teamMembers(i)
tmp.Value(“loginID”) = teamLoginIDs(i)
json.Value(“team”) = xojo.data.GenerateJSON(json2)
//snipped code that saves to a file
The code to parse the JSON text representation:
[code]Protected Sub Constructor()
//snipped code to read in the text into the variable “data as text”
dim json as xojo.Core.Dictionary = xojo.data.ParseJSON(data)
loginID = json.Value(“loginID”)
Name = json.Value(“Name”)
TeamNumber = json.Value(“TeamNumber”)
Section = json.Value(“Section”)
Time = json.Value(“Time”)
dim tmpStr as Text = json.Value(“team”)
dim json2() as xojo.Core.Dictionary = xojo.data.ParseJSON(tmpStr) //Type mismatch exception here, even though tmpStr matches what is created earlier
for i as Integer = 0 to 2
Is there something that I am doing wrong, or is this a limitation of Xojo.Data.ParseJSON?
Thanks for your help,
There’s no need to call ParseJSON a second time in your line that generates the type mismatch error. Instead:
dim json2() as auto = json.Value("team")
And you can delete the line above that creates tmpStr.
I’m not sure that’s right. The value of tmpStr which equals
which is still a JSON string. When creating the JSON object in the save method I create the array of dictionaries, generate the JSON of that and store it in
json.Value("team") then generate the JSON for json.
It works for me and my whole app reads JSON results from web services. But looking at this blog post from Paul it seems that you might just be able to dim json2 as dictionary instead of auto.
Also when saving an array of JSON within other JSON, I don’t call GenerateJSON for the array and again for the container. I just call it once for the container and it generates the JSON for the container (root) dictionary plus any sub-dictionaries and arrays of dictionaries. So maybe check that your JSON is valid too; there are many free online JSON validators.
Right, but shouldn’t it be an array of dictionaries since I passed an array of dictionaries when I was generating the JSON? Maybe I’m approaching this wrong and shouldn’t convert the array of dictionaries into JSON before storing it, but instead just make
json.Value("team") = json2?
I’ve got to run (literally…meeting my running trainer in 2 minutes) but here’s how I store an array of dictionaries within an array of dictionaries:
dim entityDict as new Dictionary
entityDict.Value ("InspectionTaskId") = InspectionGUID
entityDict.Value ("InspectionReportId") = InspectionReportGUID
dim areasDict() as Auto
for each area as InspectionArea in Areas
dim areaDict as new Dictionary
areaDict.Value ("Id") = area.InspectionAreaGUID
areaDict.Value ("Number") = area.Number
areaDict.Value ("Name") = area.Name
areaDict.Value ("Note") = area.Note
areaDict.Value ("IsDeleted") = area.Deleted
dim photosDict() as Auto
for each doc as Document in area.Documents
dim photoDict as new Dictionary
photoDict.Value ("DocumentStorageId") = doc.DocumentGUID
photoDict.Value ("Note") = doc.Notes
photoDict.Value ("IsDeleted") = doc.Deleted
areaDict.Value ("Photos") = photosDict()
entityDict.Value ("ReportAreas") = areasDict
'Convert the dictionary
dim requestContent as text = GenerateJSON(entityDict)
//Next POST the request...
Edit: I only do one GenerateJSON after all the arrays of dictionaries have been created.
Ok, thanks for that. I got it to work by eliminating the second Generate/Parse JSON and by assigning json.Value(“team”) to an array of Auto and looping through that array, assigning the auto to a temporary dictionary. I guess the problem for me was thinking that the handling of the JSON and reconstruction of objects by ParseJSON was not returning objects in the same form as I passed into GenerateJSON, but instead using an array of Auto instead of dictionary. This is probably expected behavior, but it does mean that code which turns an array of dictionaries into JSON cannot work in the exact opposite direction of how the dictionaries were created originally.
What would be nice is a way to serialize a class into and out of JSON. I work with a bunch of C# guys (they do the web services) and this is all just handled for them.