問(wèn)題描述
我嘗試序列化從 Entity Data Model .edmx 和我使用時(shí)自動(dòng)生成的 POCO 類
I tried to serialize POCO class that was automatically generated from Entity Data Model .edmx and when I used
JsonConvert.SerializeObject
我收到以下錯(cuò)誤:
檢測(cè)到類型 System.data.entity 的錯(cuò)誤自引用循環(huán)發(fā)生.
Error Self referencing loop detected for type System.data.entity occurs.
我該如何解決這個(gè)問(wèn)題?
How do I solve this problem?
推薦答案
這是最好的解決方案https://docs.microsoft.com/en-us/archive/blogs/hongyes/loop-reference-handling-in-web-api
(我已經(jīng)選擇/嘗試過(guò)這個(gè),和其他許多人一樣)
json.net 序列化程序有一個(gè)忽略循環(huán)引用的選項(xiàng).將以下代碼放入 WebApiConfig.cs
文件中:
The json.net serializer has an option to ignore circular references. Put the following code in WebApiConfig.cs
file:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
簡(jiǎn)單的修復(fù)將使序列化程序忽略將導(dǎo)致循環(huán)的引用.但是,它有局限性:
The simple fix will make serializer to ignore the reference which will cause a loop. However, it has limitations:
- 數(shù)據(jù)丟失循環(huán)引用信息
- 修復(fù)僅適用于 JSON.net
- 如果有很深的引用鏈,則無(wú)法控制引用的級(jí)別
如果你想在非 api 的 ASP.NET 項(xiàng)目中使用這個(gè)修復(fù),你可以在 Global.asax.cs
中添加上述行,但首先添加:
If you want to use this fix in a non-api ASP.NET project, you can add the above line to Global.asax.cs
, but first add:
var config = GlobalConfiguration.Configuration;
如果你想在 .Net Core 項(xiàng)目中使用它,你可以將 Startup.cs
更改為:
If you want to use this in .Net Core project, you can change Startup.cs
as:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
修復(fù) 2:全局保留循環(huán)引用
第二個(gè)修復(fù)與第一個(gè)類似.只需將代碼更改為:
Fix 2: Preserving circular reference globally
This second fix is similar to the first. Just change the code to:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;
應(yīng)用此設(shè)置后,數(shù)據(jù)形狀將發(fā)生變化.
The data shape will be changed after applying this setting.
[
{
"$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"
}
]
$id 和 $ref 保留所有引用并使對(duì)象圖級(jí)別平坦,但客戶端代碼需要知道形狀更改才能使用數(shù)據(jù),并且它也僅適用于 JSON.NET 序列化程序.
The $id and $ref keeps the all the references and makes the object graph level flat, but the client code needs to know the shape change to consume the data and it only applies to JSON.NET serializer as well.
此修復(fù)是在模型類上裝飾屬性以控制模型或?qū)傩约?jí)別的序列化行為.要忽略該屬性:
This fix is decorate attributes on model class to control the serialization behavior on model or property level. To ignore the property:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
[IgnoreDataMember]
public virtual ICollection<Product> Products { get; set; }
}
JsonIgnore 用于 JSON.NET,IgnoreDataMember 用于 XmlDCSerializer.保留參考:
JsonIgnore is for JSON.NET and IgnoreDataMember is for XmlDCSerializer. To preserve reference:
// 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)]
用于 JSON.NET,[DataContract(IsReference = true)]
用于 XmlDCSerializer.注意:在類上應(yīng)用DataContract
后,需要將DataMember
添加到要序列化的屬性中.
JsonObject(IsReference = true)]
is for JSON.NET and [DataContract(IsReference = true)]
is for XmlDCSerializer. Note that: after applying DataContract
on class, you need to add DataMember
to properties that you want to serialize.
這些屬性可以應(yīng)用在 json 和 xml 序列化器上,并提供對(duì)模型類的更多控制.
The attributes can be applied on both json and xml serializer and gives more controls on model class.
這篇關(guān)于JSON.NET 錯(cuò)誤檢測(cè)到類型的自引用循環(huán)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!