settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;html
第二个修复与第一个相似。只需将代码更改成:数据库
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/59078428json
Self referencing loop detected......的错误app
解决方案:oop
1 增长 [JsonIgnore] 过滤关联,使其不参与序列化。测试
这个方法简单粗暴。可是你就没办法获取关联的json对象。this
2 序列化时,使用以下代码,list是model对象(只适合关联对象较少).net
(可是通过楼主测试,关联比较多,比较复杂时,仍是没卵用,直接卡死。这个问题的缘由呼之欲出,也是因为主外键对象互相深度循环,牵涉到的实体层较多,关联对象更多,就不赘述了)代理
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
string result = JsonConvert.SerializeObject(list, settings);code
为了引用方便,咱们能够做为扩展方法:
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: }
包含调用将包含全部记录的参考数据。
json.net序列化器支持忽略全局设置的循环引用。一个快速解决方案是将下面的代码放在WebApiConfig.cs文件中:
1: config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
简单的修复将使序列化程序忽略会致使循环的引用。可是,它有局限性:
第二个修复与第一个相似。只需将代码更改成:
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序列化程序。
此修补程序在模型类上装饰属性以控制模型或属性级别上的序列化行为。忽略该属性:
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: }
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