I tried to serialize POCO class that was automatically generated from Entity Data Model .edmx and when I used
JsonConvert.SerializeObject
I got the following error:
检测到类型系统的自引用循环出错.数据实体发生.
How do I solve this problem?
I tried to serialize POCO class that was automatically generated from Entity Data Model .edmx and when I used
JsonConvert.SerializeObject
I got the following error:
检测到类型系统的自引用循环出错.数据实体发生.
How do I solve this problem?
That was the best solution https://docs.microsoft.com/en-us/archive/blogs/hongyes/loop-reference-handling-in-web-api
(I have chosen/tried this one, as have many others)
json.net序列化程序有一个忽略循环引用的选项.将以下代码放入WebApiConfig.cs
文件中:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore;
The simple fix will make serializer to ignore the reference which will cause a loop. However, it has limitations:
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项目中使用此选项,您可以将Startup.cs
更改为:
var mvc = services.AddMvc(options =>
{
...
})
.AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
第二个修复类似于第一个修复.只需将代码更改为:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
= Newtonsoft.Json.PreserveReferencesHandling.Objects;
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保留了所有引用,并使对象图级别平坦,但客户机代码需要知道形状更改以使用数据,并且它只适用于JSON.NET序列化程序.
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.
// 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
.
The attributes can be applied on both json and xml serializer and gives more controls on model class.