Das war die beste Lösung https://learn.microsoft.com/en-us/archive/blogs/hongyes/loop-reference-handling-in-web-api
Fix 1: Globales Ignorieren der Kreisreferenz
(Ich habe diese Option gewählt/ausprobiert, wie viele andere auch)
Der json.net-Serializer verfügt über eine Option zum Ignorieren zirkulärer Referenzen. Fügen Sie den folgenden Code in WebApiConfig.cs
Datei:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
Die einfache Lösung führt dazu, dass der Serialisierer den Verweis ignoriert, was zu einer Schleife führt. Sie hat jedoch Einschränkungen:
- Die Daten verlieren die Schleifenreferenzinformationen
- Die Korrektur gilt nur für JSON.net
- Die Ebene der Referenzen kann nicht kontrolliert werden, wenn es eine tiefe Referenzkette gibt
Wenn Sie diesen Fix in einem Nicht-API-ASP.NET-Projekt verwenden möchten, können Sie die obige Zeile zu Global.asax.cs
, aber zuerst hinzufügen:
var config = GlobalConfiguration.Configuration;
Wenn Sie dies in .Net-Kern Projekt, können Sie die Startup.cs
als:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Fix 2: Globale Beibehaltung der Kreisreferenz
Diese zweite Korrektur ist ähnlich wie die erste. Ändern Sie einfach den Code in:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;
Die Datenform wird nach Anwendung dieser Einstellung geändert.
[
{
"$id":"1",
"Category":{
"$id":"2",
"Products":[
{
"$id":"3",
"Category":{
"$ref":"2"
},
"Id":2,
"Name":"Yogurt"
},
{
"$ref":"1"
}
],
"Id":1,
"Name":"Diary"
},
"Id":1,
"Name":"Whole Milk"
},
{
"$ref":"3"
}
]
Die $id und $ref hält die alle Verweise und macht das Objekt Graphen Ebene flach, aber der Client-Code muss wissen, die Form zu ändern, um die Daten zu konsumieren und es gilt nur für JSON.NET serializer als gut.
Fix 3: Referenzattribute ignorieren und beibehalten
Dieser Fix schmückt Attribute der Modellklasse, um das Serialisierungsverhalten auf Modell- oder Eigenschaftsebene zu steuern. Um die Eigenschaft zu ignorieren:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
[IgnoreDataMember]
public virtual ICollection<Product> Products { get; set; }
}
JsonIgnore ist für JSON.NET und IgnoreDataMember ist für XmlDCSerializer. Um die Referenz zu erhalten:
// Fix 3
[JsonObject(IsReference = true)]
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
// Fix 3
//[JsonIgnore]
//[IgnoreDataMember]
public virtual ICollection<Product> Products { get; set; }
}
[DataContract(IsReference = true)]
public class Product
{
[Key]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public virtual Category Category { get; set; }
}
JsonObject(IsReference = true)]
ist für JSON.NET und [DataContract(IsReference = true)]
ist für XmlDCSerializer. Beachten Sie, dass: nach der Anwendung DataContract
auf Klasse, müssen Sie hinzufügen DataMember
auf Eigenschaften, die Sie serialisieren möchten.
Die Attribute können sowohl auf json als auch auf xml serializer angewendet werden und bieten mehr Kontrolle über die Modellklasse.