J'essaie de faire un simple retour JSON mais j'ai des problèmes ci-dessous.
public JsonResult GetEventData()
{
var data = Event.Find(x => x.ID != 0);
return Json(data);
}
J'obtiens un HTTP 500 à l'exception comme indiqué dans le titre de cette question. J'ai aussi essayé
var data = Event.All().ToList()
Cela a posé le même problème.
Est-ce un bug ou mon implémentation?
ScriptIgnore
attribut. stackoverflow.com/questions/1193857/subsonic-3-0-0-2-structs-ttScriptIgnore
attribut sur la propriété Tournament.Game et cela a bien fonctionné :)Réponses:
Il semble qu'il existe des références circulaires dans votre hiérarchie d'objets qui ne sont pas prises en charge par le sérialiseur JSON. Avez-vous besoin de toutes les colonnes? Vous pouvez sélectionner uniquement les propriétés dont vous avez besoin dans la vue:
Cela rendra votre objet JSON plus léger et plus facile à comprendre. Si vous disposez de nombreuses propriétés, AutoMapper peut être utilisé pour mapper automatiquement entre les objets DTO et les objets View.
la source
J'ai eu le même problème et résolu par
using Newtonsoft.Json;
la source
Cela se produit en fait parce que les objets complexes sont ce qui provoque l'échec de l'objet json résultant. Et cela échoue parce que lorsque l'objet est mappé, il mappe les enfants, qui mappe leurs parents, faisant apparaître une référence circulaire. Json prendrait un temps infini pour le sérialiser, donc il prévient le problème avec l'exception.
Le mappage Entity Framework produit également le même comportement et la solution consiste à ignorer toutes les propriétés indésirables.
En expliquant simplement la réponse finale, tout le code serait:
Cela peut également être le suivant si vous ne souhaitez pas que les objets se trouvent dans une
Result
propriété:la source
Pour résumer, il existe 4 solutions à cela:
Solution 1: désactivez ProxyCreation pour le DBContext et restaurez-le à la fin.
Solution 2: utilisation de JsonConvert en définissant ReferenceLoopHandling pour ignorer les paramètres du sérialiseur.
Les deux solutions suivantes sont les mêmes, mais l'utilisation d'un modèle est préférable car il est fortement typé.
Solution 3: renvoyez un modèle qui inclut uniquement les propriétés nécessaires.
Solution 4: renvoyez un nouvel objet dynamique qui inclut uniquement les propriétés nécessaires.
la source
JSON, comme xml et divers autres formats, est un format de sérialisation basé sur une arborescence. Il ne vous aimera pas si vous avez des références circulaires dans vos objets, comme le serait «l'arbre»:
Il existe souvent des moyens de désactiver la navigation le long d'un certain chemin; par exemple, avec
XmlSerializer
vous pouvez marquer la propriété parent commeXmlIgnore
. Je ne sais pas si cela est possible avec le sérialiseur json en question, ni siDatabaseColumn
a des marqueurs appropriés ( très peu probable, car il faudrait référencer chaque API de sérialisation)la source
C'est à cause du nouveau modèle DbContext T4 qui est utilisé pour générer les entités EntityFramework. Afin de pouvoir effectuer le suivi des modifications, ce modèle utilise le modèle Proxy, en enveloppant vos jolis POCO avec eux. Cela provoque alors les problèmes lors de la sérialisation avec JavaScriptSerializer.
Alors les 2 solutions sont:
Vous pouvez désactiver la génération automatique des proxies en la paramétrant sur la configuration du contexte
context.Configuration.ProxyCreationEnabled = false;
Très bien expliqué dans l'article ci-dessous.
http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/
la source
Utilisation de Newtonsoft.Json: Dans votre méthode Global.asax Application_Start, ajoutez cette ligne:
la source
ajouter
[JsonIgnore]
aux propriétés virtuelles de votre modèle.la source
Évitez de convertir directement l'objet table. Si des relations sont définies entre d'autres tables, cela peut générer cette erreur. Au contraire, vous pouvez créer une classe de modèle, attribuer des valeurs à l'objet de classe, puis le sérialiser.
la source
Les réponses fournies sont bonnes, mais je pense qu'elles peuvent être améliorées en ajoutant une perspective «architecturale».
Enquête
MVC's Controller.Json
la fonction fait le travail, mais elle est très faible pour fournir une erreur pertinente dans ce cas. En utilisantNewtonsoft.Json.JsonConvert.SerializeObject
, l'erreur spécifie exactement quelle est la propriété qui déclenche la référence circulaire. Ceci est particulièrement utile lors de la sérialisation de hiérarchies d'objets plus complexes.Une bonne architecture
Il ne faut jamais essayer de sérialiser des modèles de données (par exemple des modèles EF), car les propriétés de navigation d'ORM sont la voie vers la perdition en matière de sérialisation. Le flux de données doit être le suivant:
Les modèles de service peuvent être obtenus à partir de modèles de données à l'aide de mappeurs automatiques (par exemple Automapper ). Bien que cela ne garantisse pas l'absence de références circulaires, une conception appropriée devrait le faire: les modèles de service devraient contenir exactement ce que le consommateur de service a besoin (c'est-à-dire les propriétés).
Dans ces rares cas, lorsque le client demande une hiérarchie impliquant le même type d'objet à différents niveaux, le service peut créer une structure linéaire avec une relation parent-> enfant (en utilisant uniquement des identifiants, pas des références).
Les applications modernes ont tendance à éviter de charger des structures de données complexes à la fois et les modèles de service doivent être minces. Par exemple:
la source
J'utilise le correctif, car j'utilise Knockout dans les vues MVC5.
En action
fonction
la source
Vous pouvez remarquer les propriétés qui provoquent la référence circulaire. Ensuite, vous pouvez faire quelque chose comme:
la source
la source
Une alternative plus simple pour résoudre ce problème consiste à renvoyer une chaîne et à formater cette chaîne en json avec JavaScriptSerializer.
Il est important de la partie "Sélectionner", qui choisit les propriétés que vous souhaitez dans votre vue. Certains objets ont une référence pour le parent. Si vous ne choisissez pas les attributs, la référence circulaire peut apparaître, si vous prenez simplement les tableaux dans leur ensemble.
Ne faites pas cela:
Faites ceci à la place si vous ne voulez pas la table entière:
Cela permet de rendre une vue avec moins de données, juste avec les attributs dont vous avez besoin, et accélère votre Web.
la source