Question

Je vais avoir des problèmes avec une référence circulaire lorsque je tente de sérialiser un objet retourné par EF4 CTP5. Im en utilisant le code première approche et simple des années poco pour mon modèle.

J'ai ajouté [ScriptIgnore] attributs à toutes les propriétés qui fournissent une référence de retour à un objet et fâcheusement tout semble fonctionner très bien si j'instancier manuellement de la poco, à savoir qu'ils serialise à JSON fin, et l'attribut scriptignore est reconnu. Cependant, lorsque je tente de sérialiser un objet retourné de la DAL je reçois la référence circulaire exception « Une référence circulaire a été détectée lors de la sérialisation un objet de type « System.Data.Entity.DynamicProxies.xxxx » »

J'ai essayé plusieurs façons de retreiving les données, mais ils ont tous se coincer avec cette erreur:

    public JsonResult GetTimeSlot(int id) {
        TimeSlotDao tsDao = new TimeSlotDao();
        TimeSlot ts = tsDao.GetById(id);
        return Json(ts);
    }

La méthode fonctionne mieux comme ci-dessous légèrement plutôt que l'objet dynamique intervalle de temps approximé provoquant la refference circulaire l'objet de son rendez-vous.

    public JsonResult GetTimeSlot(int id) {
        TimeSlotDao tsDao = new TimeSlotDao();
            var ts = from t in tsDao.GetQueryable()
                 where t.Id == id
                 select new {t.Id, t.StartTime, t.Available, t.Appointment};
        return Json(ts);
    }

Toutes les idées ou solutions à ce problème?

Mise à jour Je préférerais utiliser la sortie de la boîte sérialiseur si possible bien Json.Net via NuGet est ok comme une alternative que j'espère son possible de l'utiliser comme je voulais aussi ...

Était-ce utile?

La solution

J'ai eu un problème similaire avec un IIS hébergé service WCF et de sérialisation des objets POCO avec la classe DataContractJsonSerializer. Le construit en JSON sérialiseur ne semble pas gérer des références circulaires du tout. J'ai pu la contourner en manipulant la sérialisation moi-même en utilisant le JSON.net sérialiseur, et juste retour des chaînes de JSON de mes méthodes. Le sérialiseur JSON.net a une option d'ignorer les références circulaires que JSON lui-même ne les supporte pas.

Autres conseils

Peu importe ce que je faisais les procurations dynamiques gardé d'être un point d'achoppement, je suis allé aussi loin que la suppression de toutes les références circulaires dans mon modèle! mais le problème persiste.

J'ai essayé Json.Net mais le même problème se produisait.

En fin de compte, je suis tombé sur un post sur l'aide d'une commande JavaScriptConverter

http: / /hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/

Mis en œuvre le code et bobs votre tout oncle a travaillé

Je résolu ce problème sans avoir à recourir à un sérialiseur JSON externe. Dans un ProxyCreation je désactivé nutshull dans le constructeur de mon contexte de l'objet.

Je ne sais pas pourquoi cela fonctionne, mais j'ai posté une question de suivi ici.

J'ai utilisé le ContractResolver suivant. Notez que je hérité de la CamelCaseContractPropertyResolver pour obtenir cette fonctionnalité aussi, mais vous pouvez aussi hériter directement de DefaultContractResolver.

using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json.Serialization;

namespace MyNamespace
{
    /// <summary>
    /// This class enables EntityFramework POCO objects to be serialized. In some cases POCO
    /// objects are subclassed by a proxy which has an additional member _entityWrapper. This
    /// object prevents serialization (circular references and references to non-serializable types).
    /// This removes the _entityWrapper from the list of members to be serialized.
    /// </summary>
    public class ContractResolver : CamelCasePropertyNamesContractResolver
    {
        protected override List<MemberInfo> GetSerializableMembers(Type objectType)
        {
            if (objectType.FullName.StartsWith("System.Data.Entity.DynamicProxies."))
            {
                var members = base.GetSerializableMembers(objectType);
                members.RemoveAll(memberInfo => memberInfo.Name == "_entityWrapper");
                return members;
            }
            return base.GetSerializableMembers(objectType);
        }
    }
}

Pour l'utiliser, créez votre sérialiseur puis définissez la propriété ContractResolver à une nouvelle instance de cette classe:

var ser = JsonSerializer.Create(sJsonSerializerSettings);            
ser.ContractResolver = new ContractResolver(); 

Je l'ai rencontré ce problème aussi. Les réponses à ce sujet contient des solutions numériques. Mais les meilleures solutions différentes pour les différents cas avec des explications et de plus sans mesure sérialisés j'ai trouvé dans l'article de Hongye Sun - gestion de boucle de référence dans l'API Web .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top