我有一个实体框架实体,我想将其序列化为json对象。我环顾四周,发现json.net(http://james.newtonking.com/projects/json-net.aspx)应该能够使用“开箱即用”的循环引用来序列化对象。所以我尝试使用
string json = JsonConvert.SerializeObject(/* my ef entity */);
但我仍然得到同样的错误。问题可能是我需要使用ReferenceLoopHandling.Ignore
和ContractResolver
,但我不知道如何使用它们。任何帮助深表感谢!感谢
答案 0 :(得分:17)
为了解决这个问题,我将我的实体转换为基于POCO的Code First。要执行此操作,请在edmx窗口中右键单击并选择:
添加代码生成项>代码标签> EF POCO实体生成器。
请注意,如果您没有看到它,可能需要使用nuget进行安装。
在运行时,EF会将代理类添加到这些对象以进行跟踪,但它们往往会搞乱序列化过程。为了防止这种情况,我们可以简单地将ProxyCreationEnabled设置为false,如下所示:
var context = new YourEntities();
context.Configuration.ProxyCreationEnabled = false;
var results = context.YourEntity.Take(100).ToList();
然后,您可以通过省略默认引用循环来安全地返回JSON.NET序列化数据,如下所示:
return JsonConvert.SerializeObject(results, Formatting.Indented,
new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
答案 1 :(得分:9)
另一种解决方案是将[JsonIgnore]
属性添加到您的导航属性中。
例如:
using System;
using System.ComponentModel.DataAnnotations.Schema;
[Serializable]
public class Entity
{
public int EntityID { get; set; }
public string EntityName { get; set; }
[JsonIgnore]
public virtual Parent Parent { get; set; }
[JsonIgnore]
public virtual List<Child> Children { get; set; }
}
答案 2 :(得分:6)
我使用以下解决方案克隆我的实体,没有关于实体上的数据属性所需的技巧,并保留了我的表循环引用。我甚至有实体指向对方没有任何问题。 序列化所需的库是Json.Net(Newtonsoft.Json dll)。
private static T CloneObject<T>(T obj)
{
if (obj == null)
return obj;
string ser = JsonConvert.SerializeObject(obj, Formatting.Indented,
new JsonSerializerSettings() {
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore});
return (T) JsonConvert.DeserializeObject(ser, obj.GetType());
}
使用示例:
protected object CopyObj(Object obj)
{
return CloneObject(obj);
}
var cust1 = this.cts.Customers().Where(cc => cc.Id == 3).Include(cc => cc.Addresses).FirstOrDefault();
var cust2 = CopyObj(cust1) as Customers;
//Cust2 now includes copies of the customer record and its addresses
答案 3 :(得分:2)
我的解决方案是简单地删除子实体上的父引用。
所以在我的模型中,我选择了关系并将父引用更改为内部而不是公共。
可能不是一个理想的解决方案,但对我有用。
答案 4 :(得分:1)
试试这个:首先确保poco或model有DataContract,DataMemeber并删除虚拟关键字..然后..
public string Get()
{
var list = _languageRepository.GetMany(l => l.LanguageTrans.FirstOrDefault().CultureCode == "en").ToList();
string json = JsonConvert.SerializeObject(list, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
return json;
}