我尝试序列化从 Entity Data Model .edmx 和我使用时自动生成的 POCO 类
JsonConvert.SerializeObject
我收到以下错误:
Error Self referencing loop detected for type System.data.entity occurs.
我该如何解决这个问题?
最佳答案
这是最好的解决方案 https://learn.microsoft.com/en-us/archive/blogs/hongyes/loop-reference-handling-in-web-api
修复 1:全局忽略循环引用
(我已经选择/尝试过这个,和其他许多人一样)
json.net 序列化程序有一个忽略循环引用的选项。将以下代码放入 WebApiConfig.cs
文件中:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
简单的修复将使序列化程序忽略将导致循环的引用。但是,它有局限性:
- 数据丢失循环引用信息
- 修复仅适用于 JSON.net
- 如果有很深的引用链,则无法控制引用的级别
如果你想在非 api 的 ASP.NET 项目中使用这个修复,你可以在 Global.asax.cs
中添加上述行,但首先添加:
var config = GlobalConfiguration.Configuration;
如果你想在 .Net Core 项目中使用它,你可以将 Startup.cs
更改为:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
修复 2:全局保留循环引用
第二个修复与第一个类似。只需将代码更改为:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;
应用此设置后,数据形状将发生变化。
[
{
"$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 保留所有引用并使对象图级别平坦,但客户端代码需要知道形状更改才能使用数据,并且它也仅适用于 JSON.NET 序列化程序。
修复 3:忽略并保留引用属性
此修复是在模型类上装饰属性以控制模型或属性级别的序列化行为。要忽略该属性:
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。 保留引用:
// 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。注意:在类上应用DataContract
后,需要将DataMember
添加到要序列化的属性中。
这些属性可以应用在 json 和 xml 序列化器上,并提供对模型类的更多控制。
关于c# - JSON.NET 错误检测到类型的自引用循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7397207/