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!!
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.structmetadat
...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)#" >
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.
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.
Copy link to clipboard
Copied
Please read "compatible"