其他分享
首页 > 其他分享> > (转)Json Self referencing loop

(转)Json Self referencing loop

作者:互联网

 


settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

 

修复2:保留全局循环引用

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

   1: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
   2:      = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
   3: config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
   4:      = Newtonsoft.Json.PreserveReferencesHandling.Objects;

 

https://blog.csdn.net/hanjun0612/article/details/59078428

 

 

Self referencing loop detected......的错误

 

解决方案:

1 增加  [JsonIgnore]  过滤关联,使其不参与序列化。

这个方法简单粗暴。但是你就没办法获取关联的json对象。

 

2 序列化时,使用如下代码,list是model对象(只适合关联对象较少)

(但是经过楼主测试,关联比较多,比较复杂时,还是没卵用,直接卡死。这个问题的原因呼之欲出,也是由于主外键对象互相深度循环,牵涉到的实体层较多,关联对象更多,就不赘述了)

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string result = JsonConvert.SerializeObject(list, settings);

为了引用方便,我们可以作为扩展方法:
public static class Extension
{
public static string ToJsonString<T>(this T list)
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string result = JsonConvert.SerializeObject(list, settings);
return result;
}
}

---------------------
作者:正怒月神
来源:CSDN
原文:https://blog.csdn.net/hanjun0612/article/details/59078428
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 


http://www.bubuko.com/infodetail-2525998.html

 

模型中有循环引用是很常见的。例如,以下模型显示双向导航属性:

   1: public class Category 
   2: { 
   3:     public Category() 
   4:     { 
   5:         Products = new Collection<Product>(); 
   6:     } 
   7:     
   8:     public int Id { get; set; } 
   9:     public string Name { get; set; } 
  10:     public virtual ICollection<Product> Products { get; set; } 
  11: } 
  12:  
  13: public class Product 
  14: { 
  15:     public int Id { get; set; } 
  16:     public string Name { get; set; } 
  17:     public virtual Category Category { get; set; } 
  18: } 

通过生成EF API控制器与Web API一起使用时,默认情况下不起作用。使用json.net序列化器序列化时会发生以下错误:

Self referencing loop detected for property ‘Category‘ with type 
‘System.Data.Entity.DynamicProxies.Category_A97AC61AD05BA6A886755C779FD3F96E86FE903ED7C9BA9400E79162C11BA719‘. 
Path ‘[0].Products[0]‘ 

发生此错误是因为序列化程序不知道如何处理循环引用。(在xml序列化程序中也出现类似的错误)

禁用代理并包含引用

EF代理不适用于POCO数据序列化。有几种  解决方法。为了简单起见,我们只是在数据上下文类中禁用它:

   1: public CircularReferenceSampleContext() : base("name=CircularReferenceSampleContext") 
   2: { 
   3:     Database.SetInitializer(new CircularReferenceDataInitializer()); 
   4:     this.Configuration.LazyLoadingEnabled = false; 
   5:     this.Configuration.ProxyCreationEnabled = false; 
   6: } 

但是,在禁用代理之后,导航属性不会被延迟加载。因此,从数据库中检索数据时必须包含参考。将脚手架控制器代码更改为: 

   1: public IEnumerable <Product> GetProducts()
   2: { 
   3:     return db.Products.Include(p => p.Category).AsEnumerable();
   4: } 

包含调用将包含所有记录的参考数据。

修复1:全局忽略循环引用

json.net序列化器支持忽略全局设置的循环引用。一个快速解决方案是将下面的代码放在WebApiConfig.cs文件中:

   1: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

简单的修复将使序列化程序忽略会导致循环的引用。但是,它有局限性:

修复2:保留全局循环引用

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

   1: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
   2:      = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
   3: config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
   4:      = Newtonsoft.Json.PreserveReferencesHandling.Objects;

数据形状将在应用此设置后更改。

   1: [{ “$ ID” :“1” , “类别”:{ “$ ID” :“2” , “产品”:[{ “$ ID” :“3” , “类别”:{ “$ REF “:”2“ },”ID“:2, ” 名称“:”酸奶“ },{ ”$ REF“ :”1“ }],”ID“:1, ” 名称“:”日记“ }, ” Id“:1,“名称”:“全脂牛奶” },{ “$ ref”:“3” }]

$ id和$ ref保留所有引用,并使对象图级别保持不变,但客户端代码需要知道形状更改以消费数据,并且它仅适用于JSON.NET序列化程序。

修复3:忽略并保留参考属性

此修补程序在模型类上装饰属性以控制模型或属性级别上的序列化行为。忽略该属性:

   1: public class Category 
   2: { 
   3:     public int Id { get; set; } 
   4:     public string Name { get; set; } 
   5:     
   6:     [JsonIgnore] 
   7:     [IgnoreDataMember] 
   8:     public virtual ICollection<Product> Products { get; set; } 
   9: } 
 JsonIgnore用于JSON.NET,IgnoreDataMember用于XmlDCSerializer。 
为了保持参考:
   1: // Fix 3 
   2: [JsonObject(IsReference = true)] 
   3: public class Category 
   4: { 
   5:     public int Id { get; set; } 
   6:     public string Name { get; set; } 
   7:  
   8:     // Fix 3 
   9:     //[JsonIgnore] 
  10:     //[IgnoreDataMember] 
  11:     public virtual ICollection<Product> Products { get; set; } 
  12: } 
  13:  
  14: [DataContract(IsReference = true)] 
  15: public class Product 
  16: { 
  17:     [Key] 
  18:     public int Id { get; set; } 
  19:  
  20:     [DataMember] 
  21:     public string Name { get; set; } 
  22:  
  23:     [DataMember] 
  24:     public virtual Category Category { get; set; } 
  25: } 

[JsonObject(IsReference = true)]适用于JSON.NET,[DataContract(IsReference = true)]适用于XmlDCSerializer。请注意:在类上应用DataContract后,您需要将DataMember添加到要序列化的属性。

这些属性可以应用于json和xml序列化器,并且可以为模型类提供更多的控制。

参考官方解决方案:https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7

 

 

 

标签:Category,set,get,Self,Json,referencing,序列化,public,ReferenceLoopHandling
来源: https://www.cnblogs.com/stableboy/p/11066264.html