web-dev-qa-db-fra.com

Comment réparer l'erreur de référence circulaire lors du traitement avec Json

Cette question fait partie de mon message d'origine ici Get Data Into Extjs GridPanel

Ci-dessous, mon contrôleur qui lit les données de sql db, puis j'essaie d'encoder le résultat en JSON et de renvoyer les données à ma 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();

    } 

C'est là que réside le problème, avec le code ci-dessus, j'obtiens ma table gridview sans données lors de l'exécution de gridview.js, mais si j'accède directement à la méthode de mon contrôleur comme celle-ci

http://localhost:55099/GridView/writeRecord

Je reçois cette erreur,

Une référence circulaire a été détectée lors de la sérialisation d'un objet de type 'System.Globalization.CultureInfo'. Description: Un non géré une exception s'est produite lors de l'exécution de la demande Web en cours. Veuillez consulter la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code. Détails de l'exception: System.InvalidOperationException: une référence circulaire a été détectée lors de la sérialisation d'un objet de type 'System.Globalization.CultureInfo'.

Puis-je avoir une aide s'il vous plait..

20
EagleFox

J'utilise l'outil suivant pour sérialiser et désérialiser JSON:

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

Il est très facile à utiliser et très léger.

Lors de la sérialisation, nous utilisons cette option:

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

Il ignore les références circulaires.

Aussi json.net de newtonking est extrêmement rapide.

Les autres options consistent à utiliser les DTO et à les mapper via Automapper comme mentionné par Diver.

Edit: je soupçonne que votre magasin est faux:

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

C'est parce que quelque chose à l'intérieur de CultureInfo a une référence à lui-même (ce type) et en cours de conversion en JSON, il échoue. Pour éviter cette situation, vous devez utiliser ViewModels (renvoyer au client uniquement les informations nécessaires). Vous pouvez en savoir plus ici http://blogs.msdn.com/b/dphill/archive/2009/01/31/the-viewmodel-pattern.aspx

Dans votre situation, vous devez créer des ViewModels pour vos données, convertir vos données en ces types de données et les renvoyer convertis en JSON. Dans le but de convertir de Model en ViewModel, envisagez d'utiliser AutoMapper http://automapper.codeplex.com/ ou un outil similaire.

5
berliner