2010-12-14 61 views
1

J'ai une application MVC-3 (RC1) en utilisant Entity Framework 4.Comment puis-je éviter une référence circulaire lors de la sérialisation Entity Framework classe

Je souhaite retourner un objet JSON d'une action du contrôleur. Cet objet est référencé par d'autres objets, qui renvoient évidemment la référence.

Je reçois ainsi l'erreur de référence circulaire suivante:

Server Error in '/' Application.

A circular reference was detected while serializing an object of type 'Application.Models.ReferenceObject'.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: A circular reference was detected while serializing an object of type 'Application.Models.ReferenceObject'.

NB: application & ReferenceObject remplacent évidemment pour l'espace de noms réel/objet.

Selon Stack Overflow: Circular reference exception when serializing LINQ to SQL classes, cela peut être surmonté en utilisant JSON.Net; Cependant, je voudrais éviter cela et à la place essayer d'exclure les propriétés de référence fautives de l'objet en cours de sérialisation.

Qu'est-ce que je veux dire?

Je veux faire quelque chose comme ceci:

IList<ReferenceObject> list = Repository.GetReferenceObjects(); 
return Json(list.**<method>**("ObjectsReferencingThis")); 

**<method>** est une méthode qui fait le contraire à la méthode ObjectQuery(Of T).Include et ObjectsReferencingThis est la propriété qui est à l'origine de la référence circulaire.

NB: Je ne souhaite pas supprimer ces propriétés ou créer des POCO car cela n'affecte que la sérialisation Json.

Toute personne pouvant vous aider s'il vous plaît?

:)

Répondre

2

J'ai eu un problème similaire quand travaillé sur un de mon projet précédent. Voici ce que je fini par faire:

IList<Product> list = Repository.GetProducts(); 
    var collection = products.Select(product => new 
     { 
      id = product.Id, 
      name = product.Name, 
      detailUrl = product.DetailUrl, 
      imageLargeUrl = product.ThumbNailUrl, 
      tagtitle = product.Name.ToUpper(), 
      tagheader = "Words our cherished patrons use to describe this product", 
      tagwords = from tag in product.Tags group tag by tag.Name into words select new { name =   words.Key, weight = words.Count() } 
     }); 

var result = new {id = inquiry.Id, products = collection, }; 
return this.Jsonp(result); 

Voici comment le résultat JSON ressemblerait à ceci:

{ 
"id" : 2, 
"products" : [{ 
    "id" : "3605970008857", 
    "name" : "TITLE1", 
    "detailUrl" : "http://www.urlhere.com", 
    "tagwords" : [{ 
     "name" : "roses", 
     "weight" : 1 
    }, 
    { 
     "name" : "cotton", 
     "weight" : 1 
    }, 
    { 
     "name" : "happy", 
     "weight" : 1 
    }] 
}, 
{ 
    "id" : "3605970019891", 
    "name" : "TITLE2", 
    "detailUrl" : "http://www.urlhere.com", 
    "tagwords" : [] 
}], 

}

Vous pouvez également ajouter d'autres propriétés de vous REFERENCEE objets le résultat que vous souhaitez, à afficher dans votre objet Json :)

+0

Salut @laurvasile, eh oui, cela a été la méthode que j'utilise comme une "solution de contournement" aussi bien. Je ne suis pas content à 100% car ce n'est pas exactement dynamique ... tout changement au Model doit alors être reflété dans cette conversion manuelle de JSON. Je pense que ce serait beaucoup plus efficace si vous pouviez simplement exclure un champ/propriété/référence dans le cadre de la requête LINQ, similaire à la fonction INCLUDE. –

+0

accepté comme réponse (bien que ce soit en fait une "solution de contournement" imho) –

0

J'ai fait une solution très triviale qui n'est pas recommandée si vous avez une très grande liste

letters=UserOperations.GetDepartmentLettersForSecretary(pageNumber, pageSize,(Session["User"] as User).DepartmentID.Value, (Session["User"] as User).ID); 

foreach (Letter letter in letters) 
{ 
    letter.LetterStatus.Letters = null; 
} 

le problème de circular reference dans mon cas est en LetterStatus.Letters donc je Iterated through the list et assigned it to null

que je vous ai dit que son not recommended si vous avez very big list