json.net;序列化实体框架对象(循环引用错误)

本文关键字:循环 引用 错误 对象 框架 net 序列化 实体 json | 更新日期: 2023-09-27 18:13:32

我有一个实体框架实体,我想序列化为json对象。我环顾四周,发现json.net (http://james.newtonking.com/projects/json-net.aspx)应该能够序列化对象与循环引用"开箱即用"。所以我试着用

string json = JsonConvert.SerializeObject(/* my ef entity */);

但是我仍然得到相同的错误。问题可能是我需要使用ReferenceLoopHandling.IgnoreContractResolver,但我不确定如何使用它们。任何帮助都非常感激!由于

json.net;序列化实体框架对象(循环引用错误)

为了解决这个问题,我首先将实体转换为基于POCO的代码。为此,右键单击edmx窗口并选择:

添加代码生成项> code选项卡> EF POCO Entity Generator

请注意,如果您没有看到它,您可能需要将其与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 
    });

另一个解决方案是将[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; }
}

我使用以下解决方案来克隆实体,实体上的数据属性不需要任何技巧,并且保留了表循环引用。我甚至让实体相互指向,没有任何问题。序列化所需的库是Json。Net(牛顿软件)。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

我的解决方案是简单地删除子实体上的父引用。

因此,在我的模型中,我选择了关系,并将Parent引用更改为Internal而不是Public。

可能不是一个理想的解决方案,但对我来说是有效的。

试试这个:首先确保poco或模型有数据合约,数据成员和删除虚拟关键字…然后…

 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;
    }