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

Joh*_*han 13 c# asp.net entity-framework json.net

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

string json = JsonConvert.SerializeObject(/* my ef entity */);
Run Code Online (Sandbox Code Playgroud)

但我仍然得到同样的错误.问题可能是我需要使用ReferenceLoopHandling.Ignore和a ContractResolver,但我不知道如何使用它们.任何帮助深表感谢!谢谢

Zia*_*iad 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();
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过省略默认引用循环来安全地返回JSON.NET序列化数据,如下所示:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    });
Run Code Online (Sandbox Code Playgroud)

  • 'ReferenceLoopHandling.Ignore`的+1 - 节省了我的一天! (5认同)

Kaa*_*kçü 10

另一种解决方案是[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; }
}
Run Code Online (Sandbox Code Playgroud)


Sva*_*inn 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());
    }
Run Code Online (Sandbox Code Playgroud)

用法示例:

    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
Run Code Online (Sandbox Code Playgroud)


Ant*_*ain 4

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

因此,在我的模型中,我选择了关系并将父引用更改为内部引用而不是公共引用。

可能不是所有人的理想解决方案,但对我有用。