3

EDIT 3 Coldfusion 9.0には以下の問題があり、9.0.1に更新すると実際にこれが修正されます

SerializeJSON を使用してクエリ結果をエンコードするアプリケーションがあります。

#SerializeJSON('Ok works fine')#

残念ながら、数字から末尾のゼロを削除します:

#SerializeJSON(12345.50)#

手動で同じ値を文字列にすると、同じことが起こります

#SerializeJSON('12345.50')#

どうすればこれを防ぐことができますか?

編集- 私のシナリオの詳細

データベース (Oracle) には、これらの例の値が行に格納されています

  • benefactor_id : 0000729789 varchar2(10)
  • life_gift_credit_amt : 12345.50 数値(14,2)

Coldfusion 9.0.1 (問題がある場合は cfscript) を使用してクエリを実行すると、RC ダンプが表示されます。id 文字列には先頭のゼロが保持されていますが、数値列では末尾のゼロが削除されていることに注意してください。 ここに画像の説明を入力 それは興味深いことですが、以下のようにクエリを手動で作成して末尾のゼロを保持できるため、元の問題には関係ありませんが、serializeJSON で失われます。 ここに画像の説明を入力

クエリ結果を取得し、serializeJSON を使用して値をエンコードします。JSON は jquery Datatables ajax によって消費されます。Miguel-F が言及したように、id 文字列が数値になり、「.0」が追加されていることに注意してください。

<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>  

私はもともとシリアライズJSONの代わりにjsStringFormatを使用していましたが、コメントテキスト領域にアポストロフィのectが含まれているため、これは無効な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""
    },
4

2 に答える 2

3

これは少し不可解です... CF 9でもテストしました。シリアル化されたデータ (サービスとして渡す、ページに出力するなど) で何をしているのかよくわからないので、いくつかのテスト パターンをまとめました。考えられる解決策の 1 つは、sing 値をシリアル化しようとしている場合だけです - しないでください。シリアル化せずに数値に対して逆シリアル化を実際に実行でき、末尾の 0 を削除するだけです。それ以外の場合は、単一の値をシリアル化する必要があり、末尾の 0 を削除したくない場合は、変数に引用符を含めるように設定します。

<cfset manualserial = '"111.10"'>
<cfdump var="#DeSerializeJson(manualserial)#">

この時点で、Deserialize を使用して、111.10 の出力で 0 を維持していることを確認できます。以下に追加のテストをいくつか示します。配列をシリアル化して末尾の 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>
于 2013-05-22T13:01:55.240 に答える
2

コメントより抜粋

この質問の元の投稿者 (OP) は、ColdFusion 9.0.1 でこの問題が発生していると最初に報告しました。結局のところ、彼らは実際には ColdFusion 9.0.0 を実行していました。SerializeJSON()Adobe はバージョン 9.0.1 で関数が数値を処理する方法を変更したため、これは重要です。サーバーがバージョン 9.0.1 にアップグレードされたとき、これらの問題は解決されました。

Raymond Camden によるこのブログ投稿では、9.0.1 で行われた変更について説明しています - CF901 JSON の変更に満足していませんか?

そのブログ投稿で、彼は、バージョン 9.0.1 の HotFix 1 - Cumulative Hotfix 1 (CHF1) for ColdFusion 9.0.1で入力され、修正されたバグ 83638 について言及しています。

バージョン 9.0.1 で JSON のBugBaseを検索すると、OP と同じ問題がいくつか報告されています。

これらの報告されたバグは、OPが最初に報告しなかった別の問題、つまり a.0が整数にも追加されていることにも言及していました。議論の後半で、OPは彼らもこの動作を見ていることを確認しました. これにより、使用されている ColdFusion のバージョンを確認したところ、9.0.1 ではないことが判明しました。

于 2013-05-23T19:09:57.657 に答える