1

J'utilise Ef 4.1 et j'ai un objet POCO que je voudrais sérialiser en JSON, j'ai lu qu'il y a un problème à le faire en utilisant le chargement paresseux mais je Je ne suis pas sûr que je peux parce qu'un Message peut avoir une collection de Message.Entité framework sérialiser POCO à JSON

Y at-il un moyen de le faire? Sirialiser ce genre d'objet en JSON?

Mon objet Message ressemble:

public class Message 
{ 
    [Key] 
    public int Id { get; set; } 
    public int? ParentId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 

    public DateTime CreatedAt { get; set; } 
    public DateTime? LastModified { get; set; } 

    public virtual User User { get; set; } 

    public virtual Message Parent { get; set; } 

    public virtual ICollection<Message> Children { get; set; } 
} 

Répondre

2

Le problème est des références circulaires. Un moyen facile d'éviter cela est d'utiliser Json.Net http://james.newtonking.com/projects/json-net.aspx au lieu du sérialiseur MVC json par défaut. La dernière version de Json.Net sérialisera les objets avec des références circulaires sorties de la boîte. http://james.newtonking.com/projects/json/help/PreserveObjectReferences.html pour plus d'informations sur le problème

+0

Merci! 'ReferenceLoopHandling.Ignore' et un' ContractResolver' personnalisé ont fait l'affaire :-) –

0

Que diriez-vous ceci:

  • Marquez votre classe comme [Serializable]
  • Utilisez le JsonSerializer sérialiser votre objet à JSON.
  • Peut-être utiliser un chargement passionné sur les propriétés de votre requête EF?
Message msg = new Message(); 
var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(msg.GetType()); 
MemoryStream ms = new MemoryStream(); 
serializer.WriteObject(ms, msg); 
string json = Encoding.Default.GetString(ms.ToArray()); 


[Serializable] 
public class Message 
{ 
} 
+0

merci pour la réponse détaillée, mais j'ai peur que les propriétés virtuelles ne soient pas chargées de cette façon ... –

+0

@CD: qu'est-ce qui me manque? La propriété 'virtual' sérialisée juste bien pour la collection et les propriétés uniques: http://i.imgur.com/9mkW3.png –

+0

Dans EF toute ICollection virtuelle sera chargée paresseuse .. –

1

charge Désireuse à l'aide Include(). LINQ Exemple:

var serializeMe = (from m in MyContext.Message.Include("User") where m.Id == someValue select m).ToList(); 

qui révèleront EF pour charger la propriété de navigation de l'utilisateur tout de suite au lieu de chargement paresseux, et le sérialiseur ne devrait avoir aucun problème avec elle alors.

+0

Y compris l'entité liée a résolu un problème J'avais en train de sérialiser un graphe d'objet EF parce que j'étais capable de retirer le mot-clé virtuel de la propriété incriminée dans ma classe. Merci! – marc

0

Eh bien, laisse aller par des pièces.

¿Pourquoi cela se passe-t-il?

Parce que vous avez des propriétés virtuelles. Si vous utilisez EF, vous en avez réellement besoin si vous utilisez le chargement paresseux. Vous pouvez EF votre configurent pour ne pas le faire par cet exemple:

 context.Configuration.ProxyCreationEnabled = false; 

où le contexte est votre ObjectContext ou DbContext ... ce en supposant que vous utilisez EF. Mais pour la plupart des scénarios, ce n'est pas une bonne approche.

Solution possible

Comme je le dis toujours: « il n'y a pas de bonnes ou de mauvaises solutions, juste différentes manières et cela dépend du contexte », en disant que, vous pouvez créer des objets dynamiques.

Si vous suffit de sérialisation un objet unique, vous pouvez faire quelque chose comme ça

 Json(new {@property1=yourObject.property1, @property2=yourObject.property2}) 

Si vous avez une liste, eh bien, vous pouvez le faire:

 var list = new List<dynamic>(); 

     foreach(var item in myRepository.GetAll()) 
     { 
      list.Add(new 
      { 
       @property1= item.property1, 
       @property2= item.property2, 
       @property3= item.property3 
      }); 
     } 
     return Json(list, JsonRequestBehavior.DenyGet); 

I essayé de rendre cela aussi générique que possible. J'espère que cela peut aider quelqu'un !! Cordialement, bonne journée!:)