簡體   English   中英

json.net; 序列化實體框架對象(循環引用錯誤)

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

我有一個實體框架實體,我想序列化為json對象。 我環顧四周,發現json.net(http://james.newtonking.com/projects/json-net.aspx)應該能夠序列化具有循環引用的對象。 所以我嘗試使用

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

但即時通訊仍然收到相同的錯誤。 問題可能是我需要使用ReferenceLoopHandling.IgnoreContractResolver ,但是我不確定如何使用它們。 任何幫助深表感謝! 謝謝

為了解決這個問題,我將實體轉換為基於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 
    });

另一個解決方案是將[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(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

我的解決方案是簡單地刪除我的子實體上的父引用。

因此,在我的模型中,我選擇了關系並將“父代”引用更改為“內部”而不是“公共”。

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

嘗試以下操作:首先確保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