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

   : public class Category
: {
: public Category()
: {
: Products = new Collection<Product>();
: }
:
: public int Id { get; set; }
: public string Name { get; set; }
: public virtual ICollection<Product> Products { get; set; }
: }
:
: public class Product
: {
: public int Id { get; set; }
: public string Name { get; set; }
: public virtual Category Category { get; set; }
: }

通过生成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数据序列化。有几种  解决方法。为了简单起见,我们只是在数据上下文类中禁用它:

   : public CircularReferenceSampleContext() : base("name=CircularReferenceSampleContext")
: {
: Database.SetInitializer(new CircularReferenceDataInitializer());
: this.Configuration.LazyLoadingEnabled = false;
: this.Configuration.ProxyCreationEnabled = false;
: }

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

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

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

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

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

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

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

  • 数据丢失循环参考信息
  • 该修补程序仅适用于JSON.net
  • 如果存在深度参考链,则无法控制参考级别

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

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

   : config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
: = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
: config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling
: = Newtonsoft.Json.PreserveReferencesHandling.Objects;

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

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

$ 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序列化器,并且可以为模型类提供更多的控制。

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

JSON.NET的Self referencing loop detected with type的原因以及解决办法的更多相关文章

  1. EF关于报错Self referencing loop detected with type的原因以及解决办法

    1)具体报错 { "Message": "出现错误.", "ExceptionMessage": "“ObjectContent` ...

  2. .NET JSON 转换 Error ” Self referencing loop detected for type“

    在进行实体转换为Json格式报错如下图: Self referencing loop detected for property 'md_agent' with type 'System.Data.E ...

  3. c# json 序列化时遇到错误 error Self referencing loop detected for type

    参考网址:http://blog.csdn.net/adenfeng/article/details/41622255 在写redis缓存帮助类的时候遇到的这个问题,本来打算先序列化一个实体为json ...

  4. Self referencing loop detected with type

    json.net namespace EFDAL{    using System;    using System.Collections.Generic;    using Newtonsoft. ...

  5. Newtonsoft.Json转换强类型DataTable错误:Self referencing loop detected with type ......

    问题,在使用Newtonsoft.Json对强类型的DataTable进行系列化时会出现循环引用错误 解决办法,不要直接系列化强类型的DataTable,改为 JsonConvert.Serializ ...

  6. Json Self referencing loop detected

    Self referencing loop detected......的错误 解决方案: 1 增加  [JsonIgnore]  过滤关联,使其不参与序列化. 这个方法简单粗暴.但是你就没办法获取关 ...

  7. codefirst mvc Self referencing loop detected for property

    登录时,json序列化用户类时提示错误"Self referencing loop detected for property--",经过5个小时的查找,发现原因可能是,用户类包含 ...

  8. Self referencing loop detected for property 错误

    EF 序列化返回json时 报错:Self referencing loop detected for property 解决方案:在webapiconfig.cs文件中,增加设置: 1.config ...

  9. ef entity转json引起的Self referencing loop

    问题简介:前段时间做项目时,将取到的entity往Redis cache里存放时报多重引用的错误. Self referencing loop detected for property 'Check ...

随机推荐

  1. 安装CentOS7,连接mysql提示密码错误

    1.grep 'temporary password' /var/log/mysqld.log 如果上面命令没有查看到密码 2.修改my.cnf文件.在mysqld下加入skip-grant-tabl ...

  2. python random 模块的用法

    Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...

  3. 20165226 2017-2018-4 《Java程序设计》第6周学习总结

    20165226 2017-2018-4 <Java程序设计>第6周学习总结 教材学习内容总结 第八章 常用实用类 string类 并置 两个常量进行并置,得到的仍是常量. public ...

  4. 由路由器AP隔离引起的WEB服务不能访问的问题

    最近在自己的电脑上运行了一个Web服务,发现它只能被本机访问,无法在同一个局域网的其它设备访问. 于是在网上搜索了各种资料,通通都是在操作系统层面来分析解决问题的. 而我怎么尝试都不成功的情况下,差点 ...

  5. 前端插件之Bootstrap Switch 选择框开关控制

    简介 Bootstrap Switch是一款轻量级插件,可以给选择框设置类似于开关的样式 它是依赖于Bootstrap的一款插件 下载 下载地址 在线引用 导入 因为它是依赖于Bootstrap的一款 ...

  6. 【第二十一篇】手C# MVC 微信授权登录 OAuth2.0授权登录

    首先一定要熟读,最起码过一遍微信开发者文档 微信开发者文档 文档写的很清楚 授权登录四步走 在正文开始前,我得讲清楚一个事情 敲黑板,划重点:微信一共有两个 access_token 一个是7200就 ...

  7. 【webGL入门2】点线面的绘制

    用js绘制webGL的点: THREE.Vector3 = function ( x, y, z ) { //用THREE声明的变量都是全局变量.this.x = x || 0;this.y = y ...

  8. zoj 3950 how many nines

    https://vjudge.net/problem/ZOJ-3950 题意: 给出两个日期,计算从第一个日期开始到第二个日期,每一天的日期中的9加起来一共有多少个. 思路: 看题解补的题.首先看这题 ...

  9. cookie的实现原理

    cookie技术通过在请求和响应报文中写入cookie信息来控制客户点的状态 cookie会根据从服务器端发送的响应报文内的一个叫做set-cookie的首部字段信息,通知客户端保存cookie 当下 ...

  10. 关于terraform的状态管理

    我们想在aws创建3台主机,使用ansible和terraform都是可以实现的. 用ansible可能是这样子的: - ec2: count: 10 image: ami-40d281120 ins ...