带有MVC3和EF4 CTP5w的JSON序列化的循环引用exception

当我尝试序列化通过EF4 CTP5返回的对象时,我遇到循环引用问题。 我使用代码第一种方法和简单的poco为我的模型。

我已经将[ScriptIgnore]属性添加到任何提供对象的反向引用的属性中,并且令人烦恼的是,如果我手动实例化poco的话,每个似乎工作正常,即它们串行化为JSON,并且确认了scriptignore属性。 但是,当我尝试序列化从DAL返回的对象时,我得到循环引用exception“序列化’System.Data.Entity.DynamicProxies.xxxx’类型的对象时检测到循环引用”

我已经尝试了几种方法来检索数据,但是他们都遇到了这个错误:

public JsonResult GetTimeSlot(int id) { TimeSlotDao tsDao = new TimeSlotDao(); TimeSlot ts = tsDao.GetById(id); return Json(ts); } 

下面的方法效果稍好,而不是时间段动态代理对象导致循环引用其为约会对象。

  public JsonResult GetTimeSlot(int id) { TimeSlotDao tsDao = new TimeSlotDao(); var ts = from t in tsDao.GetQueryable() where t.Id == id select new {t.Id, t.StartTime, t.Available, t.Appointment}; return Json(ts); } 

这个问题的任何想法或解决方案?

更新我希望尽可能使用开箱即用的序列化器,尽管Json.Net通过nuget可以替代我希望它可以像我预期的那样使用它…

我有一个类似的问题与IIS托管的WCF服务,并尝试使用DataContractJsonSerializer类序列化POCO对象。 内置的JSON序列化程序似乎根本不处理循环引用。 我能够通过使用JSON.net序列化器自己处理序列化,并从我的方法返回json字符串来绕过它。 JSON.net序列化程序有一个忽略循环引用的选项,因为json本身不支持它们。

无论我做了什么,动态代理仍然是一个棘手的问题,我甚至删除了模型中的所有循环引用! 但问题仍然存在。

我试过Json.Net但是发生了同样的问题。

最后,我偶然发现了一篇关于使用自定义JavaScriptConverter的post

http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/

实现了代码并且让你的叔叔一切顺利

我解决了这个问题,而不必使用外部JSON序列化程序。 在nutshull中,我在对象上下文的构造函数中禁用了ProxyCreation。

我不知道为什么会这样,但我在这里发布了一个跟进问题。

我使用了以下ContractResolver。 请注意,我inheritance了CamelCaseContractPropertyResolver以获取该function,但您也可以直接从DefaultContractResolverinheritance。

 using System; using System.Collections.Generic; using System.Reflection; using Newtonsoft.Json.Serialization; namespace MyNamespace { ///  /// This class enables EntityFramework POCO objects to be serialized. In some cases POCO /// objects are subclassed by a proxy which has an additional member _entityWrapper. This /// object prevents serialization (circular references and references to non-serializable types). /// This removes the _entityWrapper from the list of members to be serialized. ///  public class ContractResolver : CamelCasePropertyNamesContractResolver { protected override List GetSerializableMembers(Type objectType) { if (objectType.FullName.StartsWith("System.Data.Entity.DynamicProxies.")) { var members = base.GetSerializableMembers(objectType); members.RemoveAll(memberInfo => memberInfo.Name == "_entityWrapper"); return members; } return base.GetSerializableMembers(objectType); } } } 

要使用它,请创建序列化程序,然后将ContractResolver属性设置为此类的新实例:

 var ser = JsonSerializer.Create(sJsonSerializerSettings); ser.ContractResolver = new ContractResolver(); 

我也遇到过这个问题。 本主题的答案包含数字解决方案。 但是对于不同情况的最佳不同解决方案有解释,而且没有自定义序列化,我在文章中找到了Hongye SunWeb API中的循环引用处理