West Wind Internet and Client Tools
wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
Gravatar is a globally recognized avatar based on your email address. wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Govinda Berrio
  All
  Sep 25, 2019 @ 04:13pm

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!

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Rick Strahl
  Govinda Berrio
  Sep 25, 2019 @ 08:42pm

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 ---

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Govinda Berrio
  Rick Strahl
  Sep 26, 2019 @ 06:53am

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.

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Rick Strahl
  Govinda Berrio
  Sep 26, 2019 @ 09:45am

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 ---

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Govinda Berrio
  Rick Strahl
  Sep 26, 2019 @ 10:45am

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:

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Rick Strahl
  Govinda Berrio
  Sep 26, 2019 @ 08:16pm

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 ---

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Govinda Berrio
  Rick Strahl
  Sep 27, 2019 @ 06:38am

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!

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Rick Strahl
  Govinda Berrio
  Sep 27, 2019 @ 01:09pm

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 ---

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Govinda Berrio
  Rick Strahl
  Sep 27, 2019 @ 01:33pm

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!

Gravatar is a globally recognized avatar based on your email address. re: wwJsonSerializer PropertyNameCharacterFilter not filtering starting '$'
  Rick Strahl
  Govinda Berrio
  Sep 27, 2019 @ 03:13pm

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 ---

© 1996-2024