web-dev-qa-db-ja.com

Jsonを処理するときに循環参照エラーを修正する方法

この質問は私の元の投稿の一部です Get Data Into Extjs GridPanel

以下は、sql dbからデータを読み取るコントローラーです。結果をJSONとしてエンコードし、データをgridview.jsに送り返そうとしています。

public JsonResult writeRecord()
//public string writeRecord()
    {

        Response.Write("Survey Completed!");
        SqlConnection conn = DBTools.GetDBConnection("ApplicationServices2");


        string sqlquery = "SELECT Q1, Q2, Q3, Q4, Improvements, Comments FROM myTable";
        SqlDataAdapter cmd = new SqlDataAdapter(sqlquery, conn);


        DataSet myData = new DataSet();
        cmd.Fill(myData, "myTable");

        conn.Open();
        conn.Close();

        return Json(myData, JsonRequestBehavior.AllowGet);
        //return myData.GetXml();

    } 

ここに問題があります。上記のコードで、gridview.jsを実行するとデータのないグリッドビューテーブルが表示されますが、このようにコントローラーのメソッドに直接アクセスすると

http://localhost:55099/GridView/writeRecord

私はこのエラーを受け取ります、

タイプ 'System.Globalization.CultureInfo'のオブジェクトのシリアル化中に循環参照が検出されました。説明:現在のWeb要求の実行中に未処理の例外が発生しました。エラーの詳細と、エラーがコードのどこで発生したかについては、スタックトレースを確認してください。 例外の詳細:System.InvalidOperationException: 'System.Globalization.CultureInfo'タイプのオブジェクトのシリアル化中に循環参照が検出されました。

誰か助けてください。

20
EagleFox

JSONのシリアル化と逆シリアル化には次のツールを使用します。

http://james.newtonking.com/pages/json-net.aspx

それは非常に使いやすく、非常に軽量です。

シリアル化中にこのオプションを使用します:

JsonConvert.SerializeObject(myObject, Formatting.Indented, 
                            new JsonSerializerSettings { 
                                   ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
                            })

循環参照は無視されます。

また、newtonkingのjson.netは非常に高速です。

他のオプションは、DTOを使用して、Diverによって言及されているようにAutomapperを介してそれらをマップすることです。

編集:私はあなたの店が間違っていると思います:

var store = Ext.create('Ext.data.JsonStore', {      
        storeId: 'myData',
        reader: new Ext.data.JsonReader({
            root: 'myTable',
            fields: [{ name: 'Q1', type: 'int' },
                     { name: 'Q2', type: 'int' },
                     { name: 'Q3', type: 'int' },
                     { name: 'Q4', type: 'int' },
                     { name: 'Q5', type: 'int' },
                     { name: 'Improvements', type: 'string' },
                     { name: 'Comments', type: 'string'}]
        }),

        proxy: {
             type: 'json',
            url: 'GridView/writeRecord'
        }    
});  
34
Johan Haest

これは、CultureInfo内の何かがそれ自体(このタイプ)への参照を持ち、JSONへの変換中に失敗するためです。この状況を回避するには、ViewModelsを使用する必要があります(必要な情報のみをクライアントに返します)。詳細はこちら http://blogs.msdn.com/b/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx

あなたの状況では、データのViewModelを作成し、データをこれらのデータ型に変換し、JSONに変換して返します。 ModelからViewModelに変換する目的で、AutoMapper http://automapper.codeplex.com/ または同様のツールの使用を検討してください。

5
berliner