J'ai essayé de sérialiser la classe POCO qui a été générée automatiquement à partir du modèle de données d'entité .edmx et quand j'ai utilisé
JsonConvert.SerializeObject
J'ai eu l'erreur suivante:
Erreur La boucle d'auto-référencement détectée pour le type System.data.entity se produit.
Comment résoudre ce problème?
json
serialization
json.net
NevenHuynh
la source
la source
async
appel de méthode (aTask
) et j'ai oublié de préfixer l'await
instruction.Réponses:
C'était la meilleure solution https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7
Correctif 1: Ignorer globalement la référence circulaire
(J'ai choisi / essayé celui-ci, comme beaucoup d'autres)
Le sérialiseur json.net a une option pour ignorer les références circulaires. Mettez le code suivant dans le
WebApiConfig.cs
fichier:Le correctif simple obligera le sérialiseur à ignorer la référence, ce qui provoquera une boucle. Cependant, il a des limites:
Si vous souhaitez utiliser ce correctif dans un projet ASP.NET non api, vous pouvez ajouter la ligne ci-dessus
Global.asax.cs
, mais ajoutez d'abord:Si vous souhaitez l'utiliser dans le projet .Net Core , vous pouvez modifier
Startup.cs
comme:Correctif 2: conservation globale des références circulaires
Ce deuxième correctif est similaire au premier. Changez simplement le code en:
La forme des données sera modifiée après l'application de ce paramètre.
$ Id et $ ref conserve toutes les références et rend le niveau du graphique objet plat, mais le code client a besoin de connaître le changement de forme pour consommer les données et il s'applique uniquement au sérialiseur JSON.NET.
Correctif 3: ignorer et conserver les attributs de référence
Cette correction consiste à décorer les attributs de la classe de modèle pour contrôler le comportement de sérialisation au niveau du modèle ou de la propriété. Pour ignorer la propriété:
JsonIgnore est pour JSON.NET et IgnoreDataMember est pour XmlDCSerializer. Pour conserver la référence:
JsonObject(IsReference = true)]
est pour JSON.NET et[DataContract(IsReference = true)]
est pour XmlDCSerializer. Notez que: après avoir appliquéDataContract
sur la classe, vous devez ajouterDataMember
aux propriétés que vous souhaitez sérialiser.Les attributs peuvent être appliqués à la fois au sérialiseur json et xml et offrent plus de contrôles sur la classe de modèle.
la source
[JsonIgnore]
l'attribut ci-dessus a fonctionné pour moi.Utiliser JsonSerializerSettings
ReferenceLoopHandling.Error
(par défaut) affichera une erreur si une boucle de référence est rencontrée. C'est pourquoi vous obtenez une exception.ReferenceLoopHandling.Serialize
est utile si les objets sont imbriqués mais pas indéfiniment.ReferenceLoopHandling.Ignore
ne sérialisera pas un objet s'il est un objet enfant de lui-même.Exemple:
Si vous devez sérialiser un objet imbriqué indéfiniment, vous pouvez utiliser PreserveObjectReferences pour éviter une StackOverflowException.
Exemple:
Choisissez ce qui a du sens pour l'objet que vous sérialisez.
Référence http://james.newtonking.com/json/help/
la source
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
pour fonctionnerReferenceLoopHandling.Serialize
entraînera le sérialiseur à entrer dans une boucle récursive infinie et à déborder la pile.Le correctif consiste à ignorer les références de boucle et non à les sérialiser. Ce comportement est spécifié dans
JsonSerializerSettings
.Simple
JsonConvert
avec surcharge:Paramètre global avec le code
Application_Start()
dans Global.asax.cs:Référence: https://github.com/JamesNK/Newtonsoft.Json/issues/78
la source
La façon la plus simple de procéder consiste à installer Json.NET à partir de nuget et à ajouter l'
[JsonIgnore]
attribut à la propriété virtuelle de la classe, par exemple:Bien que ces jours-ci, je crée un modèle avec uniquement les propriétés que je souhaite transmettre, il est donc plus léger, n'inclut pas les collections indésirables et je ne perds pas mes modifications lorsque je reconstruis les fichiers générés ...
la source
Dans .NET Core 1.0, vous pouvez définir cela en tant que paramètre global dans votre fichier Startup.cs:
la source
Si vous utilisez .NET Core 2.x, mettez à jour votre section ConfigureServices dans Startup.cs
https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization
Si vous utilisez .NET Core 3.x sans MVC, ce serait:
Cette gestion de boucle de référence est presque obligatoire si vous utilisez Entity Framework et un modèle de conception basé sur la base de données.
la source
services.AddMvc()
?Pour sérialiser usin NEWTONSOFTJSON lorsque vous avez un problème de boucle, dans mon cas, je n'ai pas eu besoin de modifier global.asax ou apiconfig. J'utilise simplement JsonSerializesSettings en ignorant la gestion des boucles.
la source
Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize, new Newtonsoft.Json.JsonSerializerSettings() {ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
Nous pouvons ajouter ces deux lignes dans le constructeur de classe DbContext pour désactiver la boucle de référencement automatique, comme
la source
Vous pouvez également appliquer un attribut à la propriété. le
[JsonProperty( ReferenceLoopHandling = ... )]
attribut est bien adapté à cela.Par exemple:
J'espère que ça aide, Jaans
la source
Pour ignorer les références de boucle et ne pas les sérialiser globalement dans MVC 6, utilisez ce qui suit dans startup.cs:
la source
Utilisez ceci en
WebApiConfig.cs
classe:la source
Pour moi, je devais emprunter une autre voie. Au lieu d'essayer de corriger le sérialiseur JSON.Net, j'ai dû aller après le chargement paresseux sur mon contexte de données.
Je viens de l'ajouter à mon référentiel de base:
L'objet "context" est un paramètre constructeur que j'utilise dans mon référentiel de base car j'utilise l'injection de dépendances. Vous pouvez modifier la propriété ProxyCreationEnabled partout où vous instanciez votre datacontext à la place.
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
la source
J'ai eu cette exception et ma solution de travail est facile et simple,
Ignorez la propriété référencée en lui ajoutant l'attribut JsonIgnore:
Réinitialisez la propriété lorsque vous la désérialisez:
using Newtonsoft.Json;
la source
[JsonIgnore]
Équipe:
Cela fonctionne avec ASP.NET Core; Le défi de ce qui précède est de savoir comment «définir le paramètre à ignorer». Selon la façon dont vous configurez votre application, cela peut être assez difficile. Voici ce qui a fonctionné pour moi.
Cela peut être placé dans votre section ConfigureServices void public (services IServiceCollection).
la source
Les gens ont déjà parlé de l'ajout de [JsonIgnore] à la propriété virtuelle de la classe, par exemple:
Je partagerai également une autre option, [JsonProperty (NullValueHandling = NullValueHandling.Ignore)] qui omet la propriété de la sérialisation uniquement si elle est nulle:
la source
Pour .NET Core 3.0, mettez à jour la classe Startup.cs comme indiqué ci-dessous.
Voir: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-5/
la source
Placez simplement
Configuration.ProxyCreationEnabled = false;
à l'intérieur du fichier de contexte; cela résoudra le problème.la source
Mon problème résolu avec la configuration personnalisée JsonSerializerSettings:
la source
Assurez-vous également d'utiliser wait et async dans votre méthode. Vous pouvez obtenir cette erreur si votre objet n'est pas sérialisé correctement.
la source
J'étais confronté au même problème et j'ai essayé d'utiliser JsonSetting pour ignorer l'erreur d'auto-référencement, son travail un peu jusqu'à ce que j'obtienne une classe qui s'auto-référençant très profondément et mon processus dot-net se bloque sur la valeur d'écriture Json.
Mon problème
Vous pouvez voir le problème dans la classe Utilisateur qui fait référence à CompanyUser classe qui est une auto-référence.
Maintenant, j'appelle la méthode GetAll qui inclut toutes les propriétés relationnelles.
À ce stade, mon processus DotNetCore dépend de l' exécution de JsonResult, de l'écriture de valeur ... et ne vient jamais. Dans mon Startup.cs, j'ai déjà défini le JsonOption. Pour une raison quelconque, EFCore inclut une propriété imbriquée que je ne demande pas à Ef de donner.
le comportement attendu devrait être ceci
puis
à ce stade, je ne devrais obtenir que "Company.CompanyUsers.First (). User.DisplayName" et il ne devrait pas me donner Company.CompanyUsers.First (). User.CompanyUsers qui est à l'origine du problème d'auto-référencement; Techniquement, cela ne devrait pas me donner User.CompanyUsers car CompanyUsers est une propriété de navigation. Mais, EfCore devient très excité et me donne User.CompanyUsers .
J'ai donc décidé d'écrire une méthode d'extension pour que la propriété soit exclue de l'objet (elle n'exclut pas en fait, elle définit simplement la propriété sur null). Non seulement cela fonctionnera également sur les propriétés du tableau. ci-dessous est le code que je vais également exporter le paquet nuget pour les autres utilisateurs (je ne sais pas si cela aide même quelqu'un). La raison est simple car je suis trop paresseux pour écrire .Select (n => new {n.p1, n.p2});Je ne veux tout simplement pas écrire l'instruction select pour exclure seulement 1 propriété!
Ce n'est pas le meilleur code (je mettrai à jour à un moment donné) comme je l'ai écrit à la hâte et bien que cela puisse aussi aider quelqu'un qui veut exclure (définir null) dans l'objet avec des tableaux.
La classe d'extension ci-dessus vous donnera la possibilité de définir la propriété sur null pour éviter la boucle d'auto-référencement, même les tableaux.
Générateur d'expression
Coutumes:
Classes de modèles
Données factices
Cas:
Cas 1: exclure uniquement la propriété sans tableau
Cas 2: exclure une propriété avec 1 tableau
Cas 3: exclure une propriété avec 2 tableaux imbriqués
Cas 4: EF GetAll Query avec comprend
Vous avez remarqué que la méthode Explode () est également une méthode d'extension juste pour notre générateur d'expression pour obtenir la propriété de la propriété du tableau. Chaque fois qu'il existe une propriété de tableau, utilisez .Explode (). YourPropertyToExclude ou .Explode (). Property1.MyArrayProperty.Explode (). MyStupidProperty . Le code ci-dessus m'aide à éviter l'auto-référencement aussi profond que profond que je veux. Maintenant, je peux utiliser GetAll et exclure la propriété dont je ne veux pas!
Merci d'avoir lu ce gros post!
la source
Pour ne pas boucler cela a fonctionné pour moi-
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
J'ai résolu tout ici - sérialisation des enfants Entity Framework avec .Net Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606
Appréciera toutes les remarques. peut-être que quelqu'un peut l'utiliser un jour.
la source
Code C #:
la source
J'ai aimé la solution qui le fait
Application_Start()
comme dans la réponse iciApparemment, je ne pouvais pas accéder aux objets json en JavaScript en utilisant la configuration dans ma fonction comme dans la réponse de DalSoft car l'objet retourné avait "\ n \ r" partout dans la (clé, val) de l'objet.
Quoi qu'il en soit, tout ce qui fonctionne est excellent (car différentes approches fonctionnent dans différents scénarios en fonction des commentaires et des questions posées), bien qu'une méthode standard de le faire serait préférable avec une bonne documentation à l'appui de l'approche.
la source