Tuesday, August 18, 2015

Object graph for type contains cycles and cannot be serialized

This issue occurs when parent and child classes has cyclic reference and when you tries to serialize it to json or xml. See the following code which gives the error.

  1.  
  2. [DataContract]
  3. public class Family
  4. {
  5.     [DataMember]
  6.     public IList<Parent> Parents;
  7.     [DataMember]
  8.     public IList<Child> Children;
  9. }
  10.  
  11. [DataContract]
  12. public class Parent
  13. {
  14.     [DataMember]
  15.     public string Name { get; set; }
  16.     [DataMember]
  17.     public IList<Child> Children { get; set; }
  18. }
  19.  
  20. [DataContract]
  21. public class Child
  22. {
  23.     [DataMember]
  24.     public string Name { get; set; }
  25.     [DataMember]
  26.     public Parent Father { get; set; }
  27.     [DataMember]
  28.     public Parent Mother { get; set; }
  29. }

This is the sample object

  1. var dad = new Parent { Name = "John" };
  2.             var mum = new Parent { Name = "Mary" };
  3.  
  4.             var kid1 = new Child { Name = "Ann", Mother = mum, Father = dad };
  5.             var kid2 = new Child { Name = "Barry", Mother = mum, Father = dad };
  6.             var kid3 = new Child { Name = "Charlie", Mother = mum, Father = dad };
  7.  
  8.            
  9.             var listOfKids = new List<Child> { kid1, kid2, kid3 };
  10.             dad.Children = listOfKids;
  11.             mum.Children = listOfKids;
  12.  
  13.             var family = new Family { Parents = new List<Parent> { mum, dad }, Children = listOfKids };

When I tried to serialize this object using data contract serializer I go the cyclic reference error. Following is the code I used to serialize this object in to json.

  1. DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Family));
  2.          MemoryStream ms = new MemoryStream();
  3.          ser.WriteObject(ms, family);
  4.          string jsonString = Encoding.UTF8.GetString(ms.ToArray());
  5.          ms.Close();
  6.          return jsonString;

 

Json.Net gives the solution for this. I my case I don’t want cyclic references to be serialized. So following is the solution I came up.

 

1. Reference json .net to your project. Use the following nuget

PM> Install-Package NewtonSoft.Json

2.  Then add follwong using statement to your class.

  1. using Newtonsoft.Json;

3. Then use the following code. It will ignore the cyclic references and serialize the object without any issue.

var jsonSerializer = new JsonSerializer
        {
            MissingMemberHandling = MissingMemberHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
       
        var sb = new StringBuilder();
        using (var sw = new StringWriter(sb))
        using (var jtw = new JsonTextWriter(sw))
            jsonSerializer.Serialize(jtw, family);

        var result = sb.ToString();

 

for more details on this error please go here

 

Hope this helps

 

Happy Coding !!!!!!