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

Fix 1: Ignoring circular reference globally

(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:

  • 数据丢失了循环参考信息
  • 修复只适用于JSON.网
  • 如果存在较深的引用链,则引用级别无法控制

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);

Fix 2: Preserving circular reference globally

第二个修复类似于第一个修复.只需将代码更改为:

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序列化程序.

Fix 3: Ignore and preserve reference attributes

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.

Json相关问答推荐

Azure Devops Pipeline:SON字符串变量丢失所有双引号

手动解开没有可编码的SON- Swift

Jolt转换,如果任何字段为空,则将对象值设置为空

将嵌套的json中的字符串强制转换为数字

JQ如何获取特定子元素的所有父母

json 字符串到 Postgres 14 中的表视图

Powershell解析JSON文件中的键或值

如何使NiFi将数据库单列中的多个值转化为Solr索引中的数组?

VBA-JSON 嵌套集合解析为 Excel

打印与 JSON 和 PowerShell 中的模式匹配的子项的父项名称

从 JSON 响应中获取最新版本发布字段

如果有 1 个元素,如何防止 ConvertFrom-Json 折叠嵌套数组

如何使用 Newtonsoft.Json 反序列化 JSON 数组

Python Flask-Restful POST 不采用 JSON 参数

json.decoder.JSONDecodeError:期望值:第 1 行第 1 列(字符 0)

按 JSON 数据类型 postgres 排序

JSON.NET JsonConvert 与 .NET JavaScriptSerializer

使用绝对或相对路径在 curl 请求中发送 json 文件

使用 jq 如何用其他名称替换键的名称

从 JSON 到 JSONL 的 Python 转换