简体   繁体   English

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

[英]json.net; serialize entity framework object (circular reference error)

I have an entity framework entity that i want to serialize as a json object. 我有一个实体框架实体,我想序列化为json对象。 I looked around and found out that json.net (http://james.newtonking.com/projects/json-net.aspx) should be able to serialize objects with circular references "out of the box". 我环顾四周,发现json.net(http://james.newtonking.com/projects/json-net.aspx)应该能够序列化具有循环引用的对象。 So i tried using 所以我尝试使用

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

But im still getting the same error. 但即时通讯仍然收到相同的错误。 The problem might be that i need to use ReferenceLoopHandling.Ignore and a ContractResolver , but im not sure how to use them. 问题可能是我需要使用ReferenceLoopHandling.IgnoreContractResolver ,但是我不确定如何使用它们。 Any help is much appreciated! 任何帮助深表感谢! Thanks 谢谢

To get around this I converted my Entities to POCO based Code First. 为了解决这个问题,我将实体转换为基于POCO的Code First。 To do this right click inside your edmx window and select: 为此,请在edmx窗口中右键单击并选择:

Add code generation item > Code tab > EF POCO Entity Generator. 添加代码生成项>代码选项卡> EF POCO实体生成器。

Note that you might need to install it with nuget if you don't see it. 请注意,如果看不到它,可能需要使用nuget进行安装。

At runtime however EF adds proxy classes to those objects for tracking purposes but they tend to mess up with the serialization process. 但是,在运行时,EF为跟踪目的而向这些对象添加了代理类,但它们往往会干扰序列化过程。 To prevent this we can simply set ProxyCreationEnabled to false as follows: 为了防止这种情况,我们可以简单地将ProxyCreationEnabled设置为false,如下所示:

var context = new YourEntities();
context.Configuration.ProxyCreationEnabled = false;

var results = context.YourEntity.Take(100).ToList();

You can then safely return JSON.NET serialized data by omitting the default reference looping as follows: 然后,您可以通过省略默认的引用循环来安全地返回JSON.NET序列化数据,如下所示:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new JsonSerializerSettings { 
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    });

Another solution will be adding [JsonIgnore] attribute to your navigational properties. 另一个解决方案是将[JsonIgnore]属性添加到您的导航属性。

For example: 例如:

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

I used the following solution to clone my entities, no tricks where required regarding data attributes on the entities and my table circular references got preserved. 我使用以下解决方案克隆了我的实体,没有关于实体数据属性的技巧,并且保留了我的表循环引用。 I even had entities pointing to each other witout any problems. 我什至有实体互相指出,没有任何问题。 Required library for the serializaton is Json.Net (the Newtonsoft.Json dll). 序列化所需的库是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());
    }

Example usage: 用法示例:

    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

My solution was to simply remove the parent reference on my child entities. 我的解决方案是简单地删除我的子实体上的父引用。

So in my model, I selected the relationship and changed the Parent reference to be Internal rather than Public. 因此,在我的模型中,我选择了关系并将“父代”引用更改为“内部”而不是“公共”。

May not be an ideal solution for all, but worked for me. 可能不是所有人的理想解决方案,但对我有用。

Try this: First making sure poco or model has DataContract, DataMemeber and remove virtual key word..then.. 尝试以下操作:首先确保poco或模型具有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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM