Ich versuche, eine einfache JSON-Rückgabe durchzuführen, habe jedoch folgende Probleme.
public JsonResult GetEventData()
{
var data = Event.Find(x => x.ID != 0);
return Json(data);
}
Ich erhalte ein HTTP 500 mit der Ausnahme, wie im Titel dieser Frage gezeigt. Ich habe es auch versucht
var data = Event.All().ToList()
Das gab das gleiche Problem.
Ist das ein Fehler oder meine Implementierung?
ScriptIgnore
Attribut. stackoverflow.com/questions/1193857/subsonic-3-0-0-2-structs-ttScriptIgnore
Attribut auf die Tournament.Game-Eigenschaft gesetzt und es hat gut funktioniert :)Antworten:
Es scheint, dass Ihre Objekthierarchie Zirkelverweise enthält, die vom JSON-Serializer nicht unterstützt werden. Benötigen Sie alle Spalten? Sie können nur die Eigenschaften auswählen, die Sie in der Ansicht benötigen:
Dadurch wird Ihr JSON-Objekt leichter und verständlicher. Wenn Sie viele Eigenschaften haben, kann AutoMapper verwendet werden, um automatisch zwischen DTO-Objekten und Ansichtsobjekten zuzuordnen .
quelle
Ich hatte das gleiche Problem und gelöst durch
using Newtonsoft.Json;
quelle
Dies geschieht tatsächlich, weil die komplexen Objekte dazu führen, dass das resultierende JSON-Objekt ausfällt. Und es schlägt fehl, weil beim Zuordnen des Objekts die Kinder zugeordnet werden, die ihre Eltern zuordnen, wodurch ein Zirkelverweis entsteht. Json würde unendlich viel Zeit für die Serialisierung benötigen, um das Problem mit der Ausnahme zu vermeiden.
Die Entity Framework-Zuordnung führt ebenfalls zu demselben Verhalten. Die Lösung besteht darin, alle unerwünschten Eigenschaften zu verwerfen.
Wenn Sie nur die endgültige Antwort erläutern, lautet der gesamte Code:
Dies kann auch der Fall sein, wenn Sie die Objekte nicht in einer
Result
Eigenschaft haben möchten :quelle
Zusammenfassend gibt es dafür 4 Lösungen:
Lösung 1: Deaktivieren Sie ProxyCreation für den DBContext und stellen Sie ihn am Ende wieder her.
Lösung 2: Verwenden von JsonConvert durch Festlegen von ReferenceLoopHandling zum Ignorieren der Serializer-Einstellungen.
Die folgenden zwei Lösungen sind gleich, aber die Verwendung eines Modells ist besser, da es stark typisiert ist.
Lösung 3: Geben Sie ein Modell zurück, das nur die erforderlichen Eigenschaften enthält.
Lösung 4: Geben Sie ein neues dynamisches Objekt zurück, das nur die erforderlichen Eigenschaften enthält.
quelle
JSON ist wie XML und verschiedene andere Formate ein baumbasiertes Serialisierungsformat. Es wird dich nicht lieben, wenn du Zirkelverweise in deinen Objekten hast, wie der "Baum" wäre:
Es gibt oft Möglichkeiten, die Navigation entlang eines bestimmten Pfades zu deaktivieren. Mit können
XmlSerializer
Sie beispielsweise die übergeordnete Eigenschaft als markierenXmlIgnore
. Ich weiß nicht, ob dies mit dem fraglichen json-Serializer möglich ist oder obDatabaseColumn
geeignete Marker vorhanden sind ( sehr unwahrscheinlich, da auf jede Serialisierungs-API verwiesen werden müsste).quelle
Dies liegt an der neuen DbContext T4-Vorlage, die zum Generieren der EntityFramework-Entitäten verwendet wird. Um die Änderungsverfolgung durchführen zu können, verwenden diese Vorlagen das Proxy-Muster, indem Sie Ihre netten POCOs damit umschließen. Dies verursacht dann die Probleme bei der Serialisierung mit dem JavaScriptSerializer.
Dann sind die 2 Lösungen:
Sie können die automatische Generierung von Proxys deaktivieren, indem Sie sie in der Kontextkonfiguration festlegen
context.Configuration.ProxyCreationEnabled = false;
Sehr gut erklärt im folgenden Artikel.
http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/
quelle
Verwenden von Newtonsoft.Json: Fügen Sie in Ihrer Global.asax Application_Start-Methode diese Zeile hinzu:
quelle
Hinzufügen
[JsonIgnore]
zu virtuellen Eigenschaften in Ihrem Modell.quelle
Vermeiden Sie es, das Tabellenobjekt direkt zu konvertieren. Wenn Beziehungen zwischen anderen Tabellen festgelegt werden, wird dieser Fehler möglicherweise ausgelöst. Sie können vielmehr eine Modellklasse erstellen, dem Klassenobjekt Werte zuweisen und es dann serialisieren.
quelle
Die bereitgestellten Antworten sind gut, aber ich denke, sie können durch Hinzufügen einer "architektonischen" Perspektive verbessert werden.
Ermittlung
MVC's Controller.Json
Die Funktion erledigt den Job, ist jedoch in diesem Fall sehr schlecht darin, einen relevanten Fehler bereitzustellen. Bei Verwendung vonNewtonsoft.Json.JsonConvert.SerializeObject
gibt der Fehler genau an, welche Eigenschaft die Zirkelreferenz auslöst. Dies ist besonders nützlich, wenn komplexere Objekthierarchien serialisiert werden.Richtige Architektur
Man sollte niemals versuchen, Datenmodelle (z. B. EF-Modelle) zu serialisieren, da die Navigationseigenschaften von ORM der Weg zum Untergang sind, wenn es um Serialisierung geht. Der Datenfluss sollte wie folgt sein:
Servicemodelle können aus Datenmodellen unter Verwendung von Auto-Mappern (z . B. Automapper ) abgerufen werden . Dies garantiert zwar nicht das Fehlen von Zirkelverweisen, aber das richtige Design sollte dies tun: Servicemodelle sollten genau das enthalten, was der Servicekonsument benötigt (dh die Eigenschaften).
In diesen seltenen Fällen kann der Service, wenn der Client eine Hierarchie mit demselben Objekttyp auf verschiedenen Ebenen anfordert, eine lineare Struktur mit Eltern-Kind-Beziehung erstellen (wobei nur Bezeichner und keine Referenzen verwendet werden).
Moderne Anwendungen vermeiden es, komplexe Datenstrukturen gleichzeitig zu laden, und Servicemodelle sollten schlank sein. Z.B:
quelle
Ich verwende das Update, weil Knockout in MVC5-Ansichten verwendet wird.
Auf Aktion
Funktion
quelle
Sie können die Eigenschaften feststellen, die den Zirkelverweis verursachen. Dann können Sie so etwas tun wie:
quelle
quelle
Eine einfachere Alternative zur Lösung dieses Problems besteht darin, eine Zeichenfolge zurückzugeben und diese Zeichenfolge mit JavaScriptSerializer an json zu formatieren.
Es ist wichtig, dass der Teil "Auswählen" die Eigenschaften auswählt, die Sie in Ihrer Ansicht haben möchten. Einige Objekte haben eine Referenz für das übergeordnete Objekt. Wenn Sie die Attribute nicht auswählen, wird möglicherweise der Zirkelverweis angezeigt, wenn Sie nur die Tabellen als Ganzes verwenden.
Mach das nicht:
Tun Sie dies stattdessen, wenn Sie nicht die gesamte Tabelle möchten:
Dies hilft beim Rendern einer Ansicht mit weniger Daten, nur mit den von Ihnen benötigten Attributen, und beschleunigt die Ausführung Ihres Webs.
quelle