Hi,
When deserializing JSON, the resulting object does not include properties that start with '$'
For example, this works and I can access the 'values' property:
ser = CREATEOBJECT("wwJsonSerializer")
o = ser.Deserializejson('{ "id": 84, "values$": [ "govinda", "ivan" ] }')
?o.values(1)
* govinda
But this does not:
o = ser.Deserializejson('{ "id": 84, "$values": [ "govinda", "ivan" ] }')
?o.values(1)
* Property VALUES is not found
Any advice on getting this working would be appreciated.
Thank You!
This has nothing to do with the with the result from the JSON parser, but rather this is a FoxPro issue where you can't access indexers on arrays or collections in child properties. Indexers only work on variables...
DO wwJsonSerializer
ser = CREATEOBJECT("wwJsonSerializer")
o = ser.Deserializejson('{ "id": 84, "values$": [ "govinda", "ivan" ] }')
*** Indexers don't work in nested objects
* ? o.Values[1]
* ? o.Values[2]
*** Assign to var then it works
loValues = o.Values
? loValues[1]
? loValues[2]
*** Or use the Item Collection
? o.Values.Item(1)
? o.Values.Item(2)
+++ Rick ---
Hi Rick!
Thank you for your prolific work!
Maybe a better example is this: This works,
o = ser.Deserializejson('{ "id": 84, "color$": "green" }')
?o.color
* green
This does not,
o = ser.Deserializejson('{ "id": 84, "$color": "green" }')
?o.color
* Error: "Property COLOR is not found"
The only difference is that the '$' is at the beginning of the property name and not the end. Thanks for your help.
The problem here is that the property names are not valid foxpro names, so the names are fixed up. Take a look at the actual object that comes back and what the fixed up property name is.
+++ Rick ---
I thought that was the case too, but when I inspect the object, the property is not there.
Here's looking at the var in the debugger:
Here's running AMEMBERS() on it:
Vars that start with a $
are a special case. They tend to be internal vars and by default they are ignored and not rendered into the JSON.
You can turn that off with:
o = ser.Deserializejson('{ "id": 84, "$color": "green" }')
o.IgnoreDollarVars = .F.
? o.color
... and that works.
There's also a PropertyNameCharacterFilter
property that by default excludes any invalid and extended ANSI characters from so this:
ser = CREATEOBJECT("wwJsonSerializer")
o = ser.Deserializejson('{ "id": 84, "#color": "green" }')
? o.Id
? o.color
Works without any special configuration. The value can be overridden but likely not required.
+++ Rick ---
Thanks Rick!
BTW, the code that works for me is:
ser = CREATEOBJECT("wwJsonSerializer")
ser.IgnoreDollarVars = .F.
o = ser.DeserializeJson('{ "id": 84, "$color": "green" }')
? o.color
* green
Have great day!
Yeah - maybe it would be a good idea to turn that flag off by default (IgnoreDollarVars=.F.
).
The reason it's set this way is that there are some internal .NET things - generics specifically that can cause a bunch of $ based properties and they can conflict with other properties at times which is problematic. either way the option is there - I forgot that this was there until i checked again 😃
+++ Rick ---
Ah. I see. Tough call.
I do not see wwJsonSerializer.IgnoreDollarVars in the documentation.
Maybe an entry in the documentation or just this thread will be enough to help future users with this caveat.
"Why did I do it like that?" I ask myself that question all the time. LOL XD
Take it easy!
Docs have been updated (you might have to refresh to see changes).
wwJsonSerializer::IgnoreDollarVars
Note I made the change to .F.
which is not true for current versions. You might want to flip that in your wwJsonSerializer.prg
file to make this easier (while you're thinking about it).
+++ Rick ---