You might have seen my Twitter status update earlier today, which went kinda like this:
#ColdFusion.... JSON... AGAIN... AAAAAAAAAAAARRRRRRRRRRRRRGGGGGGGGGGGHHHHHHHH!!!!!!!
The degree to which ColdFusion can't get JSON right just beggars belief.
Today we discovered CF9 (and confirmed on CF10) cannot even handle bloody strings correctly.
Sorry to be all shouty and stuff, but this is just getting beyond a joke.
We don't only use ColdFusion at work, we also have a bunch of C#-written DotNet-based applications providing web services for the ColdFusion application. Today we had to pass a string to one of the .Net web services, and we simply could not coerce ColdFusion into serialising a value as a string. "Huh?" you think, and quite rightly so. The thing is with this string... it just happens to be a sequence of digits. It's not a number, it's not a numeric value. It's a string that just happens to comprise entirely of digits.
So... try to tell ColdFusion that. Go on.
Here's some code.
intValue = 123;
strValue = "#intValue#";
javaCastVariable = javaCast("String", intValue);
data = {
hardCodedString = "123",
hardCodedInt = 123,
intVariable = intValue,
intVariableQuoted = """#intValue#""",
toString = toString(intValue),
javaCast = javaCast("String", intValue),
newVariable = strValue,
javaCastVariable = javaCastVariable,
javaString = createObject("java", "java.lang.String").init(intValue)
};
json = serializeJson(data);
writeDump([data,json]);
There's some control values in there, but there's also all the ways I could think of telling ColdFusion that the value is a string. No. No. To ColdFusion they're all bloody numbers:
array | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
| ||||||||||||||||||||
2 | { "JAVACAST":123, "JAVACASTVARIABLE":123, "INTVARIABLEQUOTED":"\"123\"", "JAVASTRING":123, "INTVARIABLE":123, "HARDCODEDSTRING":123, "HARDCODEDINT":123, "NEWVARIABLE":123, "TOSTRING":123 } |
Every single bloody one of them has been converted into a number. Why, Adobe? Just why? I can understand just the basic ones in which I use an actual number, or even the ones where I used quoted numbers... CF has a guess at the type, and decides "number". Now it should not do that when the thing is quoted, irrespective of its contents, because clearly a quoted value is a string. What's even more a string is the result of a call to javaCast("string"), and especially an actual Java string object. I could also understand if I passed a string-containing-digits to a function which expected a numeric for ColdFusion to be kindly enough to cast the string to a numeric. CF is loosely-typed and this is what it should be doing. However at no stage of the "putting the value into a struct" or "serialising the struct" is there any need to mess with the values going into or already in the struct. There's no need to change the data type.
I hasten to add it's not the "putting it into the struct" bit that's screwing things up, because if I do this:
<cfoutput>#serializeJson("123")#</cfoutput>
I get this:
123
Wrong.
One might think or claim "oh yeah, but ColdFusion has no way of knowing whether it's a string or a numeric, so it's making its best guess". OK, well explain how Railo can do it just fine then?
Array | ||||||||||||||||||||||||||||||||||||||||
1 |
| |||||||||||||||||||||||||||||||||||||||
2 |
|
And for the second code example, it returns:
"123"
Adobe have fixed a lot of the JSON bugs that arose in CF9 for CF10, but this one is still broken in CF10.
I shall raise a ticket... .
Do you know what's worst about this? Having to explain to the very bemused .Net guys how - no - we cannot even pass a string to you properly. Sorry.
--
Adam