Question

Comment sérialiser un objet de structure d'entité en objet JavaScript (JSON)? J'ai essayé d'utiliser JSON.NET , mais je reçois l'exception suivante lorsque j'essaie de le sérialiser.

Exception: Newtonsoft.Json.JsonSerializationException, Message = "Boucle de référence automatique"

Hitesh

Était-ce utile?

La solution

Il semble que vous rencontriez le même problème général que le sérialiseur DataContract d'origine, en ce qui concerne les références cycliques. Alors que les objets se référant les uns aux autres sont assez communs avec les graphiques d’objets en mémoire, de telles références cycliques entraînent inévitablement des récursions infinies lorsqu’elles sont sérialisées si le sérialiseur ne les prend pas en compte de manière spécifique. Il existe peu de normes, voire aucune, pour traiter les références cycliques dans les formats de sérialisation non binaires courants (XML et JSON étant les deux systèmes les plus répandus.)

Microsoft a résolu le problème cyclique du sérialiseur DataContract dans .NET 3.5 SP1 en utilisant la sémantique ref de XML. À ma connaissance, JSON n'existe pas, ce qui pourrait expliquer pourquoi JSON.NET vous empêche de sérialiser votre graphe d'objets.

Je m'assurerais que votre graphique d'objet ne contient que des références qui sont navigables dans un sens, plutôt que dans les deux sens (c'est-à-dire uniquement d'un parent à l'autre et non d'un enfant à l'autre). Ces parents / enfants et enfants / parents sont les types les plus courants de références cycliques. Il se peut également qu’un enfant de niveau inférieur fasse en fin de compte référence à la racine du graphe, ce qui entraîne la création d’un graphe cyclique indirect (elles tendent toutefois à être beaucoup moins courantes que les boucles parent / enfant.)

Une fois que vous avez éliminé les références cycliques dans votre graphe d'objets, vous devriez être en mesure de sérialiser.

Autres conseils

J'ai eu ce problème et je l'ai résolu en ajoutant le Newtonsoft.Json.JsonIgnoreAttribute à la propriété à l'origine de la boucle. De toute évidence, cette propriété ne sera pas sérialisée. Pour résoudre ce problème, j'ai généralement à la fois l'ID de référence étrangère et la classe étrangère dans mes entités. Je réalise que ce n’est pas intuitif (ni super génial, mais c’est ce que recommande Julia Lerman dans son livre Programming Entity Framework: Code First. J'ai trouvé que cela permettait de résoudre plusieurs problèmes liés à Entity Framework.

 public class SomeEntity
 {
      [JsonIgnore]
      public ForeignEntity SomeForeignEntity {get;set;}
      public Guid ForeignEntityId {get;set;}
 }

Mise à jour: j'ai oublié de mentionner que j'avais également besoin de désactiver les serveurs proxy sur le DbContext comme suit:

dataContext.Configuration.ProxyCreationEnabled = false;

Si vous écrivez le code d'un service (ce qui semble probable si vous sérialisez), alors ce n'est probablement pas un problème, mais vous perdez certains éléments lorsque la création de proxy est désactivée. Voir ici: http://www.sellsbrothers.com/posts/Details/12665 ?? pour plus de détails.

J'utilise MS Web Api. Il ne me reste donc plus qu'à désactiver la création du proxy lors de la construction de mon contrôleur:

public class MailingApiController : ApiController
{
    public MailingApiController()
    {
        PreventDeepSerialization();
    }

    private static void PreventDeepSerialization()
    {
        var dataContext = Injector.Get<IIntertwyneDbContext>();
        dataContext.Configuration.ProxyCreationEnabled = false;
    }
      ....

Pour résoudre ce problème, j'ai converti mes entités en code d'abord basé sur POCO. Pour ce faire, cliquez à l'intérieur de votre fenêtre edmx et sélectionnez:

Ajouter un élément de génération de code > Onglet Code > Générateur d'entité EF POCO.

Notez que vous devrez peut-être l'installer avec nuget si vous ne le voyez pas.

Au moment de l'exécution, cependant, EF ajoute des classes proxy à ces objets à des fins de suivi, mais elles ont tendance à gâcher le processus de sérialisation. Pour éviter cela, nous pouvons simplement définir ProxyCreationEnabled sur false comme suit:

var context = new YourEntities();
context.Configuration.ProxyCreationEnabled = false;

var results = context.YourEntity.Take(100).ToList();

Vous pouvez ensuite renvoyer en toute sécurité des données sérialisées JSON.NET en omettant la boucle de référence par défaut comme suit:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new jsonSerializerSettings { 
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    });
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top