Web Connection
Serialize behavior
Gravatar is a globally recognized avatar based on your email address. Serialize behavior
  Harvey Mushman
  All
  Feb 9, 2019 @ 12:36pm

Nothing is broken but I wonder why more than anything else... I got caught creating a JSON string, storing it into a table and when I pass it back to the client as JSON in the REST response, the Json string within the JSON object does not get parsed back into a JSON object. Said another way, I wanted to have a JSON nested object when it arrives at the client.

The Serialize() function in the following WriteString() function is introducing a backslash into the valid JSON string. Because of this JavaScript JSON.parse() sees the JSON string as a String, not an object.

*** Optimized for perf with C code in wwIPStuff.dll
*** JsonEncodeString
LOCAL lcOutput 
lcOutput = REPLICATE(CHR(0),LEN(lcValue) * 6 + 3)
lnPointer = JsonEncodeString(lcValue,@lcOutput)
this.cOutput = this.cOutput +  WinApi_NullString(@lcOutput)

Here is an example of the JSON string creation.

loJson=CREATEOBJECT('Empty')  
ADDPROPERTY(loJson,'Messages','[{"created":"' + ToIsoDateString(DATETIME(),.t.,.f.) ;
   +'","ndx":1,"message":"Inspection Request Posted"}]')

lcJson = Serializer.Serialize( loJson )

ADDPROPERTY(loBus.oData,'cJSON',lcJson)

? loBus.oData.cJSON
{
"messages": "[{\"created\":\"2019-02-09T15:31:29Z\",\"ndx\":1,\"message\":\"Inspection Request Posted\"}]"
}

The work around is simple, create a Collection and an EMPTY class to create the array of message then add that object to the parent JSON object and Serialize() it, then work as expected.

loMessages = CREATEOBJECT('Collection')
loMessage = CREATEOBJECT('Empty')
ADDPROPERTY(loMessage,'created',DATETIME())
ADDPROPERTY(loMessage,'ndx',1)
ADDPROPERTY(loMessage,'message',"Inspection Request Posted")
loMessages.Add(loMessage)
ADDPROPERTY(loJson,'Messages',loMessages)
  

Seems like a lot of steps to just create a simple default message.

Gravatar is a globally recognized avatar based on your email address. re: Serialize behavior
  Rick Strahl
  Harvey Mushman
  Feb 9, 2019 @ 08:19pm

I'm not quite following, but I think the problem is that you are double encoding the data. First when you create the JSON and store it the data is already raw JSON. Then you are returning as a JSON response and that's encoding the data as again as a JSON string, and that'll add extra quotes and encode text inside of the string again.

You can make that still work by returning a RAW response (ie. no JSON serialization of the already serialized string) on the cached data like this:

IF llCached
   Service.IsRawResponse = .T.
   Response.ContentType = "application/json"  && not necessary because already JSON
   return lcCachedJson  && won't be encoded - sent as is
ENDIF

+++ Rick ---

© 1996-2019