Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property

Problem

When you try to serialize an object with a circular, and there’s a circular reference, you get the following exception:

Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property

For example, I have a Parent class and Child class. The Parent object has a reference to a Child object, which has a back reference to the Parent object. This is a circular reference (another way to say it is there’s a cycle in the object graph).

Parent harry = new Parent() { Name = "Harry" }; Parent mary = new Parent() { Name = "Mary" }; harry.Children = new List<Child>() { new Child() { Dad = harry, Mom = mary, Name = "Barry" } }; mary.Children = harry.Children; var json = JsonConvert.SerializeObject(harry);

When I run this code, I get the “Self referencing loop” exception.

Solution

There are a few options for solving this problem.

Option 1 – Add ReferenceLoopHandling.Ignore

You can use the ReferenceLoopHandling.Ignore option to tell Newtonsoft to ignore circular references.

var json = JsonConvert.SerializeObject(harry, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

The resulting JSON looks like this:

{ "Children": [{ "Mom": { "Name": "Mary" }, "Name": "Barry" }], "Name": "Harry" }

Because Newtonsoft is ignoring circular references, the Child’s Dad reference is null. Same thing with the Child.Mom’s Children reference.

Because there are null references, when you go to deserialize this, you may want to re-link the objects. This may lead to incorrect assumptions, so be careful if you’re taking this approach. Here’s an example of deserializing the above JSON back into a Parent object, and then re-linking:

var dad = JsonConvert.DeserializeObject<Parent>(json); dad.Children.ForEach(child => { child.Dad = dad; child.Mom.Children = dad.Children; });

Option 2 – Add JsonIgnore to the property causing the cycle

The Child class has two circular references: Mom and Dad. So put a [JsonIgnore] attribute on those properties and Newtonsoft will ignore them.

public class Child { [Newtonsoft.Json.JsonIgnore] public Parent Mom { get; set; } [Newtonsoft.Json.JsonIgnore] public Parent Dad { get; set; } public string Name { get; set; } }

Note: Using the full name of the JsonIgnore attribute because the built-in System.Text.Json also has a JsonIgnore attribute.

The resulting JSON looks like this:

{ "Children": [{ "Name": "Barry" }], "Name": "Harry" }

When you go to deserialize this, unlike with option 1, you no longer have the Mom reference, because the Mom property was ignored by Newtonsoft. If you’re storing the Mom object separately somewhere, this may not be a problem for you.

Option 3 – Remove the circular reference

You may have created a circular reference by accident, and this “Self referencing loop” exception is pointing it out to you. In this case, remove the circular reference.

In this case, I removed the Dad and Mom circular references in the Child class.

public class Child { public string Name { get; set; } }

The resulting JSON looks just like option 2.

{ "Children": [{ "Name": "Barry" }], "Name": "Harry" }

Unlike the other two options, deserialization is not a problem, because the JSON has exactly the same properties as the class.

Leave a Comment