JSON.NET的Self referencing loop detected with type的原因以及解决办法
模型中有循环引用是很常见的。例如,以下模型显示双向导航属性:
: 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; }
: }
为了保持参考:
: // 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的原因以及解决办法的更多相关文章
- EF关于报错Self referencing loop detected with type的原因以及解决办法
1)具体报错 { "Message": "出现错误.", "ExceptionMessage": "“ObjectContent` ...
- .NET JSON 转换 Error ” Self referencing loop detected for type“
在进行实体转换为Json格式报错如下图: Self referencing loop detected for property 'md_agent' with type 'System.Data.E ...
- c# json 序列化时遇到错误 error Self referencing loop detected for type
参考网址:http://blog.csdn.net/adenfeng/article/details/41622255 在写redis缓存帮助类的时候遇到的这个问题,本来打算先序列化一个实体为json ...
- Self referencing loop detected with type
json.net namespace EFDAL{ using System; using System.Collections.Generic; using Newtonsoft. ...
- Newtonsoft.Json转换强类型DataTable错误:Self referencing loop detected with type ......
问题,在使用Newtonsoft.Json对强类型的DataTable进行系列化时会出现循环引用错误 解决办法,不要直接系列化强类型的DataTable,改为 JsonConvert.Serializ ...
- Json Self referencing loop detected
Self referencing loop detected......的错误 解决方案: 1 增加 [JsonIgnore] 过滤关联,使其不参与序列化. 这个方法简单粗暴.但是你就没办法获取关 ...
- codefirst mvc Self referencing loop detected for property
登录时,json序列化用户类时提示错误"Self referencing loop detected for property--",经过5个小时的查找,发现原因可能是,用户类包含 ...
- Self referencing loop detected for property 错误
EF 序列化返回json时 报错:Self referencing loop detected for property 解决方案:在webapiconfig.cs文件中,增加设置: 1.config ...
- ef entity转json引起的Self referencing loop
问题简介:前段时间做项目时,将取到的entity往Redis cache里存放时报多重引用的错误. Self referencing loop detected for property 'Check ...
随机推荐
- netty : NioEventLoopGroup 源码分析
NioEventLoopGroup 源码分析 1. 在阅读源码时做了一定的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限.为了方便 IDE 查看.跟踪.调试 代码,所以在 github ...
- 新概念英语(1-59)Is that all
Does the lady buy any chalk? A:I want some envelopes, please. B:Do you want the large size or the sm ...
- C语言的一些输出格式
%e printf()的一种输出格式 科学表示的一种浮点数 1.24==1.240000e+000 1240000==1.240000e+006 ...
- urllib.request.Request
import urllib.request #可以将url先构造成一个Request对象,传进urlopen #Request存在的意义是便于在请求的时候传入一些信息,而urlopen则不 reque ...
- php过滤表单提交的html等危险代码
表单提交如果安全做得不好就很容易因为这个表单提交导致网站被攻击了,下面我来分享两个常用的php过滤表单提交的危险代码的实例,各位有需要的朋友可参考. PHP过滤提交表单的html代码里可能有被利用引入 ...
- SpringMVC之数据传递二
上一篇学习了从url或view中传数据到Controller中,今天学习下数据从Controller传到view中,主要有4种. 一.ModelAndView 处理方法返回值类型为 ModelAndV ...
- 几个APP开发的创意
每年都有大量新APP进入市场,争夺消费者的关注.随着越来越多的APP进入主流,随着需求的变化和新技术的出现,一系列新的APP随之而来.那么目前有什么APP开发的好创意呢? 1.旅游指南APP 当你在一 ...
- ES6 new syntax of Default Function Parameters
Default Function Parameters.md Default Function Parameters function getSum(a,b){ a = (a !== undefine ...
- vue中自定义组件(插件)
vue中自定义组件(插件) 原创 2017年01月04日 22:46:43 标签: 插件 在vue项目中,可以自定义组件像vue-resource一样使用Vue.use()方法来使用,具体实现方法: ...
- 视觉slam学习之路(一)看高翔十四讲所遇到的问题
目前实验室做机器人,主要分三个方向,定位导航,建图,图像识别,之前做的也是做了下Qt上位机,后面又弄红外识别,因为这学期上课也没怎么花时间在项目,然后导师让我们确定一个方向来,便于以后发论文什么. ...