Highlighted

SerializeJSON(struct) on CF 2018 works differently than on CF 2016 and is breaking my code base.

New Here ,
Sep 16, 2020

Copy link to clipboard

Copied

On CF2016,  when using SerializeJSON() to serialize a struct, string values like "true" would get converted to booleans in the JSON.  While this could be considered a bug, serializeJSON() has always worked like this, and our code base (client side) is expecting the boolean value when deserializing the strings. Is there any way to enable the old behavoir for the entire app / server on CF 2018?

 

 

<cfset x = {}>
<cfset x.normal = true>
<cfset x.normalStr = 'true'>

// serialize and dump
<cfdump var="#serializeJSON(x)#">
// on CF2016, we get a boolean value for normalStr
{"NORMALSTR":true,"NORMAL":true}
// on CF2018, the data type is preserved
{"NORMALSTR":"true","NORMAL":true}

 I know I can set the metadata to preserve data types, but my code base is to large to find all the various nested structs and keys that would need to have meta data description.  I'm looking for a way to make CF2018 serializeJSON() work like it did on 2016.

 

I have also added a regex to replace "true" with true, within the resulting JSON, but this is not ideal and I haven't found all the places where this is causing issues. 

 

Anyone know how to turn on the old behavoir of 2016?

 

Thanks!!

Views

63

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

SerializeJSON(struct) on CF 2018 works differently than on CF 2016 and is breaking my code base.

New Here ,
Sep 16, 2020

Copy link to clipboard

Copied

On CF2016,  when using SerializeJSON() to serialize a struct, string values like "true" would get converted to booleans in the JSON.  While this could be considered a bug, serializeJSON() has always worked like this, and our code base (client side) is expecting the boolean value when deserializing the strings. Is there any way to enable the old behavoir for the entire app / server on CF 2018?

 

 

<cfset x = {}>
<cfset x.normal = true>
<cfset x.normalStr = 'true'>

// serialize and dump
<cfdump var="#serializeJSON(x)#">
// on CF2016, we get a boolean value for normalStr
{"NORMALSTR":true,"NORMAL":true}
// on CF2018, the data type is preserved
{"NORMALSTR":"true","NORMAL":true}

 I know I can set the metadata to preserve data types, but my code base is to large to find all the various nested structs and keys that would need to have meta data description.  I'm looking for a way to make CF2018 serializeJSON() work like it did on 2016.

 

I have also added a regex to replace "true" with true, within the resulting JSON, but this is not ideal and I haven't found all the places where this is causing issues. 

 

Anyone know how to turn on the old behavoir of 2016?

 

Thanks!!

Views

64

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Adobe Community Professional ,
Sep 17, 2020

Copy link to clipboard

Copied

The definition of the function has evolved, as you can see in the history section of the serializeJson documentation. The function changed not only between CF2016 and CF2018. There was an even bigger change within CF2016 itself. In Update 2 of CF2016, support was added for struct and array serialization using metadata.

 

In fact, you can use that very feature to solve your problem. If the datatype of certain struct keys are important to your application, then use this.serialization.structmetadata to define them. 

 

Proceed as follows:

 

<!--- In Application.cfc --->
<cfset this.serialization.structmetadata = {firstName:"string", lastname:"string", normal:"boolean", normalstr1:"boolean", normalstr2:"boolean"}>

<!--- In the CFM page --->
<cfset x = {}>
<cfset x.normal = true>
<cfset x.normalStr1 = 'true'>
<cfset x.normalStr2 = 'false'>
<cfdump var="#SerializeJSON(x)#" >

 

 

 

 

 

 

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 17, 2020 0
New Here ,
Sep 20, 2020

Copy link to clipboard

Copied

Thanks for the suggestion; however, this is just one example of where this is happening, and its springled into so many parts of our application that this approach would be time-consuming and error-prone. Its a shame the default behavior changed between versions and is not backward compatible.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 20, 2020 0
Adobe Community Professional ,
Sep 20, 2020

Copy link to clipboard

Copied

Hi brookd 

You are right about that. After all, one of ColdFusion's selling points is that it is backward compitible.

 

I agree that this could be time-consuming and error-prone. Nevertheless, it is worth the effort, because it improves the code. It also has the advantage that you can implement it piecewise. 

 

Start with the most important struct keys (in this.serialization.structmetadata), the ones that must be of a certain datatype. Add more as time goes by.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 20, 2020 0
BKBK LATEST
Adobe Community Professional ,
Sep 21, 2020

Copy link to clipboard

Copied

Please read "compatible"

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Sep 21, 2020 0