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

   : 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. pymysql安装和使用

    一.pymysql安装 安装mymysql前请确认python环境已经准备好,在之前的博文http://www.cnblogs.com/newzol/p/8682176.html有说明pythonwe ...

  2. SQL Server(MySql)中的联合主键(联合索引) 索引分析

    最近有人问到这个问题,之前也一直没有深究联合索引具体使用逻辑,查阅多篇文章,并经过测试,得出一些结论 测试环境:SQL Server 2008 R2 测试结果与MySql联合索引查询机制类似,可以认为 ...

  3. Python-字符串及列表操作-Day2

    1.数据类型 1.1 变量引出数据类型 变量:用来记录状态变量值的变化就是状态的变化,程序运行的本质就是来处理一系列的变化 1.2 五大基本数据类型: 数字 字符串 列表 元组 字典 1.2.1 数字 ...

  4. api-gateway实践(16)【租户模块:修改api定义】通过mq通知【开发者模块:更新开发者集市】

    一.订阅关系 二.接收消息 dev模块接收更新本地集市

  5. HTTP协议扫盲(二)HTTP协议的请求方法、请求头和响应头

    一.HTTP请求方法 Http协议定义了很多与服务器交互的方法,最基本的有4种,分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST ...

  6. O(logN)中logN的底数

    转载:http://blog.csdn.net/jdbc/article/details/42173751 问题: 无论是计算机算法概论.还是数据结构书中, 关于算法的时间复杂度很多都用包含O(log ...

  7. POJ-1328 Radar Installation--区间选点问题(贪心)

    题目链接: https://vjudge.net/problem/POJ-1328 题目大意: 假设陆地的海岸线是一条无限延长的直线,海岛是一个个的点,现需要在海岸线上安装雷达,使整个雷达系统能够覆盖 ...

  8. [Kaggle] dogs-vs-cats之建立模型

    建立神经网络模型,下面要建立的模型如下: (上图来源:训练网络时,打开tensorboard即可观察网络结构,在下一节模型训练的时候会讲到) 下面为具体步骤: Step 0:导入相关库 import ...

  9. java之设计模式工厂三兄弟之抽象工厂模式

    [学习难度:★★★★☆,使用频率:★★★★★]  工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工 ...

  10. 【Markdown 语法】

    Markdown 语法 摘抄自MWEB Markdown 的设计哲学 Markdown 的目標是實現「易讀易寫」. 不過最需要強調的便是它的可讀性.一份使用 Markdown 格式撰寫的文件應該可以直 ...