编辑3 Coldfusion 9.0存在以下问题,更新到9.0.1确实解决了这个问题
我有一个使用SerializeJSON编码查询结果的应用程序:
#SerializeJSON('Ok works fine')#
不幸的是它会从数字中删除尾随的零:
#SerializeJSON(12345.50)#
手动如果我要将相同的值设为字符串,则会发生同样的事情
#SerializeJSON('12345.50')#
如何防止这种情况发生?
编辑 - 我的方案细节
数据库(Oracle)将这些示例值存储在一行
当我使用Coldfusion 9.0.1(cfscript,如果它重要)查询时,这里是一个RC转储,注意id字符串保留前导零,但数字列已删除尾随零。 虽然这很有趣,但它对原始问题无关紧要,因为我可以手动创建一个查询以保留如下所示的尾随零,它仍然会在serializeJSON中丢失
我获取查询结果,并使用serializeJSON对值进行编码。 JQuery由jquery Datatables ajax使用。请注意,id字符串已成为一个数字,并添加了“.0”作为Miguel-F提到的
<cfscript>
...
rc.sql = q.setsql;
rc.qResult = q.execute().getresult();
savecontent variable="rc.aaData" {
for (i=1; i <= rc.qResult.RecordCount; i++) {
writeOutput('{');
for (col=1; col <= iColumnsLen; col++) {
// the following line contains a conditional specific to this example
writeOutput('"#aColumns[col]#":#SerializeJSON(rc.qResult[aColumns[col]][i])#');
//former statement, discarded due to not being able to handle apostrophe's ... writeOutput('"#jsStringFormat(rc.qResult[aColumns[col]][i])#"');
writeOutput((col NEQ iColumnsLen) ? ',' : '');
}
writeOutput('}');
writeOutput((i NEQ rc.qResult.RecordCount) ? ',' : '');
}
};
</cfscript>
我正在使用jsStringFormat而不是serializeJSON,但由于注释文本区域包含撇号等,这将返回无效的JSON
{
"sEcho": 1,
"iTotalRecords": 65970,
"iTotalDisplayRecords": 7657,
"aaData": [
{
"nd_event_id": 525,
"benefactor_id": 729789.0,
"seq_number": 182163,
"life_gift_credit_amt": 12345.5,
"qty_requested": 2,
"b_a_comment": "#swap",
"pref_mail_name": "Jay P. Rizzi"
}
]
}
编辑2
快速旁注,如果我将序列化行更改为
writeOutput('"#aColumns[col]#": "#SerializeJSON(rc.qResult[aColumns[col]][i])#"');
然后我的结果集更改为将记录放在双引号中,但也加倍双引号字符串,同时仍然删除尾随零;它让我相信serializeJSON正在将值转换为类型?
"aaData": [
{
"nd_event_id": "525",
"benefactor_id": "729789.0",
"seq_number": "182163",
"life_gift_credit_amt": "12345.5",
"qty_requested": "2",
"b_a_comment": ""#swap"",
"pref_mail_name": ""JayP.Rizzi""
},
答案 0 :(得分:3)
这有点令人费解......我也在CF 9中测试过。不知道你在处理序列化数据(作为服务传递,在页面上输出等),我把一些测试模式放在一起。一种可能的解决方案是,如果只是尝试序列化唱歌值 - 不要。实际上,您可以在不进行序列化的情况下对数值运行反序列化,并且它所做的只是去除尾部0.否则,如果必须序列化单个值并且不希望删除尾部0,请将变量设置为包含引号< / p>
<cfset manualserial = '"111.10"'>
<cfdump var="#DeSerializeJson(manualserial)#">
此时你可以反序列化并看到它保持0,输出为111.10 下面是一些额外的测试,所以你可以看到序列化数组时会发生什么,同时试图保持尾随0 ...没有运气。但是,当我为内置的CF序列化而刚刚创建了一个序列化字符串时,保留了尾随0(请参阅下面的WriteDump示例中的var customarr和d_customarr)。
希望有所帮助。
<cfscript>
/*initial testing*/
string = SerializeJSON('Ok works fine');
numericstring = SerializeJSON('12345.50');
numeric = SerializeJSON(12345.50);
arr = SerializeJSON([12345.50,12345.10,'12345.20']);
arrFormat = SerializeJSON([NumberFormat(12345.50,'.00') & ' ',12345.10,'12345.20']);
d_string = DeSerializeJSON(string);
d_numericstring = DeSerializeJSON(numericstring);
d_numeric = DeSerializeJSON(numeric);
d_arr = DeSerializeJSON(arr);
d_arrFormat = DeSerializeJSON(arrFormat);
/*technically, there is no need to serialize a single string value, as running through DeSerialize just trims the trailing 0
if you need to do so, you would want to pass in as a string with quotation marks*/
customstring = '"12345.50"';
d_customstring = DeSerializeJSON(customstring);
customarr = '["12345.50","12345.10","12345.20"]'; //--you can format your own array instead of using CF to serialize
d_customarr = DeSerializeJSON(customarr);
WriteDump(variables);
</cfscript>
=======追加可能的解决方案b ========
我认为手动序列化记录可能是最稳定的选项,尝试这个例子,如果它有效,你应该能够将函数添加到cfc或创建一个udf进行重用。希望它有所帮助。
<cfscript>
q = QueryNew('nd_event_id,benefactor_id,seq_number,life_gift_credit_amt,qty_requested,b_a_comment,pref_mail_name',
'Integer,VarChar,Integer,Decimal,Integer,VarChar,VarChar');
r = queryaddrow(q,2);
querysetcell(q, 'nd_event_id', 525, 1);
querysetcell(q, 'benefactor_id', 0000729789, 1);
querysetcell(q, 'seq_number', 182163, 1);
querysetcell(q, 'life_gift_credit_amt', 12345.50, 1);
querysetcell(q, 'qty_requested', 2, 1);
querysetcell(q, 'b_a_comment', '##swap', 1);
querysetcell(q, 'pref_mail_name', 'Jay P. Rizzi', 1);
querysetcell(q, 'nd_event_id', 525, 2);
querysetcell(q, 'benefactor_id', 0000729790, 2);
querysetcell(q, 'seq_number', 182164, 2);
querysetcell(q, 'life_gift_credit_amt', 12345.90, 2);
querysetcell(q, 'qty_requested', 10, 2);
querysetcell(q, 'b_a_comment', '##swap', 2);
querysetcell(q, 'pref_mail_name', 'Jay P. Rizzi', 2);
WriteDump(q);
s = membershipManualSerializer(q);
public string function membershipManualSerializer(required query q){
var jsonString = '{"aaData":[';
var cols = listtoarray(q.columnList,',');
for(var i=1; i lte q.recordcount; i++){
jsonString &= "{";
for(var c=1;c lte arraylen(cols);c++){
jsonString &= '"' & cols[c] & '":"' & q[cols[c]][i] & '"';
jsonString &= (c lt arraylen(cols))? ",":"";
}
jsonString &= (i lt q.recordcount)? "},":"}]";
}
jsonString &="}";
return jsonString;
}
WriteOutput(s);
WriteDump(DeserializeJson(s));
</cfscript>
答案 1 :(得分:2)
取自评论
这个问题的原始海报(OP)最初报告说他们在ColdFusion 9.0.1中遇到了这个问题。事实证明他们实际上正在运行ColdFusion 9.0.0。这很重要,因为Adobe更改了SerializeJSON()
函数如何处理版本9.0.1中的数字。当服务器升级到9.0.1版时,这些问题已得到解决。
Raymond Camden撰写的这篇博客文章讨论了9.0.1中所做的更改 - Not happy with the CF901 JSON Changes?
在该博客文章中,他引用了已输入的错误83638,然后在HotFix 1中修复了版本9.0.1 - Cumulative Hotfix 1 (CHF1) for ColdFusion 9.0.1
如果您在版本9.0.1下搜索BugBase以获取JSON,则有几个报告与OP相同的问题。
那些报告的错误还提到了OP最初未报告的另一个问题,即.0
也被附加到整数。在讨论的后期,OP确认他们也看到了这种行为。这导致他们验证正在使用的ColdFusion版本,并发现它不是9.0.1。