Ich habe versucht, die POCO-Klasse zu serialisieren, die automatisch aus dem Entity Data Model .edmx generiert wurde, und als ich sie verwendet habe
JsonConvert.SerializeObject
Ich habe folgenden Fehler erhalten:
Fehler Es tritt eine selbstreferenzierende Schleife für den Typ System.data.entity auf.
Wie löse ich dieses Problem?
json
serialization
json.net
NevenHuynh
quelle
quelle
async
Methodenaufrufs (aTask
) serialisieren wollte und vergessen habe, derawait
Anweisung ein Präfix zu setzen .Antworten:
Das war die beste Lösung https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7
Fix 1: Zirkelverweis global ignorieren
(Ich habe dieses ausgewählt / ausprobiert, wie viele andere auch)
Der json.net-Serializer bietet die Möglichkeit, Zirkelverweise zu ignorieren. Fügen Sie den folgenden Code in die
WebApiConfig.cs
Datei ein:Durch die einfache Korrektur ignoriert der Serializer die Referenz, was zu einer Schleife führt. Es gibt jedoch Einschränkungen:
Wenn Sie diesen Fix in einem ASP.NET-Projekt ohne API verwenden möchten, können Sie die obige Zeile
Global.asax.cs
hinzufügen, aber zuerst hinzufügen:Wenn Sie dies in einem .Net Core- Projekt verwenden möchten , können Sie Folgendes ändern
Startup.cs
:Fix 2: Zirkelverweis global beibehalten
Dieser zweite Fix ähnelt dem ersten. Ändern Sie einfach den Code in:
Die Datenform wird nach dem Anwenden dieser Einstellung geändert.
Die $ id und $ ref behalten alle Referenzen bei und machen das Objektdiagramm flach, aber der Client-Code muss die Formänderung kennen, um die Daten zu verbrauchen, und dies gilt auch nur für den JSON.NET-Serializer.
Fix 3: Referenzattribute ignorieren und beibehalten
Mit diesem Fix werden Attribute für die Modellklasse dekoriert, um das Serialisierungsverhalten auf Modell- oder Eigenschaftsebene zu steuern. So ignorieren Sie die Eigenschaft:
JsonIgnore ist für JSON.NET und IgnoreDataMember ist für XmlDCSerializer. So behalten Sie die Referenz bei:
JsonObject(IsReference = true)]
ist für JSON.NET und[DataContract(IsReference = true)]
ist für XmlDCSerializer. Beachten Sie Folgendes: Nach dem AnwendenDataContract
auf die Klasse müssen SieDataMember
Eigenschaften hinzufügen , die Sie serialisieren möchten.Die Attribute können sowohl auf den JSON- als auch auf den XML-Serializer angewendet werden und bieten mehr Steuerelemente für die Modellklasse.
quelle
[JsonIgnore]
obigen Attributs hat bei mir funktioniert.Verwenden Sie JsonSerializerSettings
ReferenceLoopHandling.Error
(Standard) tritt ein Fehler auf, wenn eine Referenzschleife auftritt. Aus diesem Grund erhalten Sie eine Ausnahme.ReferenceLoopHandling.Serialize
ist nützlich, wenn Objekte verschachtelt, aber nicht unbegrenzt sind.ReferenceLoopHandling.Ignore
serialisiert ein Objekt nicht, wenn es ein untergeordnetes Objekt von sich selbst ist.Beispiel:
Wenn Sie ein Objekt serialisieren müssen, das auf unbestimmte Zeit verschachtelt ist, können Sie PreserveObjectReferences verwenden , um eine StackOverflowException zu vermeiden.
Beispiel:
Wählen Sie aus, was für das zu serialisierende Objekt sinnvoll ist.
Referenz http://james.newtonking.com/json/help/
quelle
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
um zu funktionierenReferenceLoopHandling.Serialize
dazu, dass der Serializer in eine Endlosschleife übergeht und den Stapel überläuft.Das Update besteht darin, Schleifenreferenzen zu ignorieren und nicht zu serialisieren. Dieses Verhalten ist in angegeben
JsonSerializerSettings
.Single
JsonConvert
mit Überlastung:Globale Einstellung mit Code
Application_Start()
in Global.asax.cs:Referenz: https://github.com/JamesNK/Newtonsoft.Json/issues/78
quelle
Der einfachste Weg, dies zu tun, besteht darin, Json.NET von Nuget aus zu installieren und das
[JsonIgnore]
Attribut der virtuellen Eigenschaft in der Klasse hinzuzufügen , zum Beispiel:Obwohl ich heutzutage ein Modell nur mit den Eigenschaften erstelle, die ich durchlaufen möchte, damit es leichter ist, keine unerwünschten Sammlungen enthält und ich meine Änderungen nicht verliere, wenn ich die generierten Dateien neu erstelle ...
quelle
In .NET Core 1.0 können Sie dies als globale Einstellung in Ihrer Startup.cs-Datei festlegen:
quelle
Wenn Sie .NET Core 2.x verwenden, aktualisieren Sie den Abschnitt ConfigureServices in Startup.cs
https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization
Wenn Sie .NET Core 3.x ohne MVC verwenden, ist dies:
Diese Behandlung von Referenzschleifen ist fast obligatorisch, wenn Sie Entity Framework und das Entwurfsmuster "Datenbank zuerst" verwenden.
quelle
services.AddMvc()
?Um in NEWTONSOFTJSON zu serialisieren, wenn Sie ein Schleifenproblem haben, musste ich in meinem Fall weder global.asax noch apiconfig ändern. Ich benutze nur JsonSerializesSettings und ignoriere die Schleifenbehandlung.
quelle
Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize, new Newtonsoft.Json.JsonSerializerSettings() {ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
Wir können diese beiden Zeilen in den DbContext-Klassenkonstruktor einfügen, um die selbstreferenzierende Schleife zu deaktivieren
quelle
Sie können der Eigenschaft auch ein Attribut zuweisen. Das
[JsonProperty( ReferenceLoopHandling = ... )]
Attribut ist dafür gut geeignet.Zum Beispiel:
Hoffe das hilft, Jaans
quelle
Verwenden Sie in startup.cs Folgendes, um Schleifenreferenzen zu ignorieren und sie in MVC 6 nicht global zu serialisieren:
quelle
Verwenden Sie dies in der
WebApiConfig.cs
Klasse:quelle
Für mich musste ich einen anderen Weg gehen. Anstatt zu versuchen, den JSON.Net-Serializer zu reparieren, musste ich das Lazy Loading in meinem Datenkontext durchführen.
Ich habe dies gerade zu meinem Basis-Repository hinzugefügt:
Das "Kontext" -Objekt ist ein Konstruktorparameter, den ich in meinem Basis-Repository verwende, da ich die Abhängigkeitsinjektion verwende. Sie können die ProxyCreationEnabled-Eigenschaft überall dort ändern, wo Sie stattdessen Ihren Datenkontext instanziieren.
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
quelle
Ich hatte diese Ausnahme und meine Arbeitslösung ist einfach und unkompliziert.
Ignorieren Sie die Referenced-Eigenschaft, indem Sie das JsonIgnore-Attribut hinzufügen:
Setzen Sie die Eigenschaft zurück, wenn Sie sie deserialisieren:
mit Newtonsoft.Json;
quelle
[JsonIgnore]
Mannschaft:
Dies funktioniert mit ASP.NET Core. Die Herausforderung für das oben Gesagte besteht darin, wie Sie die Einstellung so einstellen, dass sie ignoriert wird. Je nachdem, wie Sie Ihre Anwendung einrichten, kann dies eine große Herausforderung sein. Hier ist, was für mich funktioniert hat.
Dies kann in Ihrem öffentlichen ungültigen Abschnitt ConfigureServices (IServiceCollection-Dienste) platziert werden.
quelle
Die Leute haben bereits darüber gesprochen, dass [JsonIgnore] zur virtuellen Eigenschaft in der Klasse hinzugefügt wird, zum Beispiel:
Ich werde auch eine andere Option freigeben, [JsonProperty (NullValueHandling = NullValueHandling.Ignore)], bei der die Eigenschaft bei der Serialisierung nur dann weggelassen wird, wenn sie null ist:
quelle
Aktualisieren Sie für .NET Core 3.0 die Startup.cs-Klasse wie unten gezeigt.
Siehe: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-5/
quelle
Einfach
Configuration.ProxyCreationEnabled = false;
in die Kontextdatei einfügen; Dies wird das Problem lösen.quelle
Mein mit der benutzerdefinierten Konfiguration gelöstes Problem JsonSerializerSettings:
quelle
Stellen Sie außerdem sicher, dass Sie in Ihrer Methode await und async verwenden. Sie können diesen Fehler erhalten, wenn Ihr Objekt nicht ordnungsgemäß serialisiert ist.
quelle
Ich hatte das gleiche Problem und habe versucht, mit JsonSetting den selbstreferenzierenden Fehler zu ignorieren, bis ich eine Klasse bekam, die sehr tief auf sich selbst verweist und mein Punktnetzprozess vom Json-Schreibwert abhängt.
Mein Problem
Sie können das Problem in der Benutzerklasse sehen, die auf CompanyUser verweist Klasse , die sich selbst referenziert.
Jetzt rufe ich die GetAll-Methode auf, die alle relationalen Eigenschaften enthält.
In dieser Phase hängt mein DotNetCore-Prozess an der Ausführung von JsonResult, dem Schreiben von Werten ... und kommt nie. In meiner Startup.cs habe ich bereits die JsonOption festgelegt. Aus irgendeinem Grund enthält EFCore verschachtelte Eigenschaften, die ich Ef nicht geben soll.
erwartetes Verhalten sollte dies sein
dann
Zu diesem Zeitpunkt sollte ich nur dieses "Company.CompanyUsers.First (). User.DisplayName" erhalten und es sollte mir nicht Company.CompanyUsers.First (). User.CompanyUsers geben, das das Problem der Selbstreferenzierung verursacht. Technisch sollte es mir nicht User.CompanyUsers geben, da CompanyUsers eine Navigationseigenschaft ist. Aber EfCore wird sehr aufgeregt und gibt mir User.CompanyUsers .
Daher habe ich beschlossen, eine Erweiterungsmethode für die Eigenschaft zu schreiben, die vom Objekt ausgeschlossen werden soll (sie schließt eigentlich nicht aus, sondern setzt die Eigenschaft nur auf null). Nicht nur, dass es auch mit Array-Eigenschaften funktioniert. Unten ist der Code, den ich auch für andere Benutzer exportieren werde (nicht sicher, ob dies überhaupt jemandem hilft). Der Grund ist einfach, weil ich zu faul bin, um zu schreiben. Wählen Sie (n => new {n.p1, n.p2});Ich möchte einfach keine select-Anweisung schreiben, um nur 1 Eigenschaft auszuschließen!
Dies ist nicht der beste Code (ich werde ihn irgendwann aktualisieren), da ich es eilig habe und obwohl dies jemandem helfen könnte, der das Objekt auch mit Arrays ausschließen (null setzen) möchte.
Mit der obigen Erweiterungsklasse können Sie die Eigenschaft auf null setzen, um zu vermeiden, dass die selbstreferenzierende Schleife auch Arrays enthält.
Ausdrucksgenerator
Verwendung:
Modellklassen
Dummy-Daten
Fälle:
Fall 1: Schließen Sie nur Eigenschaften ohne Array aus
Fall 2: Eigenschaft mit 1 Array ausschließen
Fall 3: Eigenschaft mit 2 verschachtelten Arrays ausschließen
Fall 4: EF GetAll-Abfrage mit Includes
Sie haben festgestellt, dass die Explode () -Methode auch eine Erweiterungsmethode ist, nur damit unser Ausdrucksgenerator die Eigenschaft von der Array-Eigenschaft abruft. Wenn eine Array-Eigenschaft vorhanden ist, verwenden Sie .Explode (). YourPropertyToExclude oder .Explode (). Property1.MyArrayProperty.Explode (). MyStupidProperty . Der obige Code hilft mir, die Selbstreferenzierung so tief wie möglich zu vermeiden. Jetzt kann ich GetAll verwenden und die Eigenschaft ausschließen, die ich nicht will!
Vielen Dank für das Lesen dieses großen Beitrags!
quelle
Da ich nicht geloopt habe, hat das bei mir funktioniert.
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Ich habe hier alles gelöst - Serialisierung von Entity Framework-Kindern mit .Net Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606
Ich werde mich über Bemerkungen freuen. Vielleicht kann es irgendwann jemand benutzen.
quelle
C # -Code:
quelle
Ich mochte die Lösung, die es macht,
Application_Start()
wie in der Antwort hierAnscheinend konnte ich mit der Konfiguration in meiner Funktion wie in DalSofts Antwort nicht auf die json-Objekte in JavaScript zugreifen, da das zurückgegebene Objekt "\ n \ r" über das gesamte (Schlüssel, Wert) des Objekts hatte.
Was auch immer funktioniert, es ist großartig (da unterschiedliche Ansätze in unterschiedlichen Szenarien funktionieren, basierend auf den gestellten Kommentaren und Fragen), obwohl eine Standardmethode mit einer guten Dokumentation, die den Ansatz unterstützt, vorzuziehen wäre.
quelle