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

22,629

Solution 1

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.

Solution 2

To get around this I converted my Entities to POCO based Code First. To do this right click inside your edmx window and select:

Add code generation item > Code tab > EF POCO Entity Generator.

Note that you might need to install it with nuget if you don't see it.

At runtime however EF adds proxy classes to those objects for tracking purposes but they tend to mess up with the serialization process. To prevent this we can simply set ProxyCreationEnabled to false as follows:

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:

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

Solution 3

Another solution will be adding [JsonIgnore] attribute to your navigational properties.

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

Solution 4

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).

    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

Solution 5

Try this: First making sure poco or model has DataContract, DataMemeber and remove virtual key word..then..

 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;
    }
Share:
22,629
Johan
Author by

Johan

Updated on January 21, 2020

Comments

  • Johan
    Johan over 4 years

    I have an entity framework entity that i want to serialize as a json object. 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". 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. Any help is much appreciated! Thanks

  • Admin
    Admin almost 8 years
    This is the right answer, the entities should reference each other. But you need to ignore the master entity property in the child.
  • Kai Hartmann
    Kai Hartmann over 7 years
    But what if I want to view the relation from the child elements point of view?
  • Luke
    Luke over 4 years
    you made my day
  • Edgar Mejía
    Edgar Mejía over 3 years
    Thanks, I think this is the best solution.