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

   : 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. solr云的简单搭建(了解)

    1.认识系统架构 1.1.集群概述 1.1.1.单点服务器的问题 我们之所以要学习集群,是因为单点服务器,存在一系列的问题. 我们以前学习的JavaEE项目,都是部署在一台Tomcat上,所有的请求, ...

  2. spring-oauth-server实践:授权方式1、2、3和授权方式4的token对象.authorities产生方式比较

    授权方式1.2.3和授权方式4的token对象.authorities产生方式不同, 前者使用user_privillege构建, 后者直接使用oauth_client_details.authort ...

  3. 开源软件:NoSql数据库 - 图数据库 Cassandra

    转载原文:http://www.cnblogs.com/loveis715/p/5299495.html Cassandra简介 在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了 ...

  4. 命名参数名(含*args , * *kw的区别)

    要限制关键字参数的名字,就可以用命名关键字参数 # coding=utf-8 # 命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数.调用方式如下 def person(name, ...

  5. 2017年Unity游戏开发视频教程(入门到精通)

    本文是我发布的一个Unity游戏开发的学习目录,以后我会持续发布一系列的游戏开发教程,都会更新在这个页面上,适合人群有下面的几种: 想要做独立游戏的人 想要找游戏开发相关工作的人 对游戏开发感兴趣的人 ...

  6. python基础——多态与多态性

    python基础--多态与多态性 1 多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 1. 序列类型有多种形态:字符串,列表,元组. 2. 动物有多种形态:人, ...

  7. Python的字典和JSON

    Python的字典和JSON在表现形式上非常相似 #这是Python中的一个字典 dic = { 'str': 'this is a string', 'list': [1, 2, 'a', 'b'] ...

  8. C++ 多态的实现及原理

    C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数.如果对象类型是派生类,就调用派生类的函数:如果对象类型是基类 ...

  9. Linux OpenGL 实践篇-1 OpenGL环境搭建

    本次实践所使用环境为CentOS 7. 参考:http://www.xuebuyuan.com/1472808.html OpenGL开发环境搭建: 1.opengl库安装 opengl库使用mesa ...

  10. [LeetCode] Monotone Increasing Digits 单调递增数字

    Given a non-negative integer N, find the largest number that is less than or equal to N with monoton ...