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

   : 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. AngularJS1.X学习笔记11-服务

    如果我没记错的话,spring里边有个service层.什么是服务呢?个人理解就是很多地方要用的,可以跨越控制器甚至是跨越模块的工具.AngularJS也为我们提供了服务这种机制,这让我们可以将一些不 ...

  2. angular路由守卫

     路由守卫是指当用户满足了某些要求之后才可以离开或者进入某个页面或者场景的时候使用.比如说只有当用户填写了用户名和密码之后才可以进入首页,比如说用户离开某个页面时明月保存信息提示用户是否保存信息后再离 ...

  3. 整理一下 System.Linq.Enumerable 类中的那些比较少用的方法

    Linq 虽然用得多,但是里面有一些方法比较少用,因此整理一下.Enumerable 类的所有方法可以在 MSDN 上查阅到:https://msdn.microsoft.com/zh-cn/libr ...

  4. python模块之PIL模块

    PIL简介 什么是PIL PIL:是Python Image Library的缩写,图像处理的模块.主要的类包括Image,ImageFont,ImageDraw,ImageFilter PIL的导入 ...

  5. Thymeleaf3语法详解和实战

    Thymeleaf3语法详解 Thymeleaf是Spring boot推荐使用的模版引擎,除此之外常见的还有Freemarker和Jsp.Jsp应该是我们最早接触的模版引擎.而Freemarker工 ...

  6. angularjs1.x版本,父子组件之间的双向绑定

    今天遇到了一个angularjs的坑, ng-repeat和ng-if会改变他所包含的html中绑定变量的作用域. angularjs自定义指令,可以定义四种变量,通过 =,@,&双向绑定,单 ...

  7. jade 详解

    简介 jade 是HTMl模板引擎,用javascript编写,可以在Node.js中使用.本文主要介绍原生node操作jade文件的方法.   安装 npm install jade 方法(API) ...

  8. css 的一些知识点的整理

    css的一些标签整理   background-attachment: scroll;背景图可滚动 background-attachment: fixed; 固定背景的位置,不随着滚动条移动而移动 ...

  9. XMLHTTPRequestObject获取服务器数据

    http://www.educity.cn/develop/526316.html 在Web客户端使用xmlhttp对象,可以十分方便的和服务器交换数据,我们可以获取和发送任何类型的数据,甚至二进制数 ...

  10. [TJOI 2010]中位数

    Description 给定一个由N个元素组成的整数序列,现在有两种操作: 1 add a 在该序列的最后添加一个整数a,组成长度为N + 1的整数序列 2 mid 输出当前序列的中位数 中位数是指将 ...