Problem
When you try to serialize an object using Newtonsoft.Json and there’s a circular reference, you get the following exception:
Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property
Here’s an example of code that results in this exception:
using Newtonsoft.Json;
var child = new Child() { Name = "Barry" };
var mom = new Parent() { Name = "Mary" };
mom.Children = new List<Child>()
{
child
};
child.Mom = mom;
var json = JsonConvert.SerializeObject(mom);
Code language: C# (cs)
The Parent object references the Child object, which references the Parent object. Hence, a circular reference (aka a cycle in the object graph). You have three options for solving this problem:
- Use ReferenceLoopingHandling.Ignore.
- Use [JsonIgnore].
- Remove the property with the circular reference.
I’ll show examples below.
Option 1 – Use ReferenceLoopHandling.Ignore
You can use the ReferenceLoopHandling.Ignore option to tell Newtonsoft to ignore circular references. Here’s an example:
var settings = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var json = JsonConvert.SerializeObject(mom, Formatting.Indented, settings);
Console.WriteLine(json);
Code language: C# (cs)
This outputs the following JSON:
{
"Name": "Mary",
"Children": [
{
"Name": "Barry"
}
]
}
Code language: JSON / JSON with Comments (json)
Notice it didn’t fully serialize the Child object. It recognized Child.Parent as a circular reference and ignored it.
Option 2 – Use [JsonIgnore] on the property with the circular reference
Use the [JsonIgnore] attribute on properties with circular references. In this example, the Child class has a Parent property, which is a circular reference. Add [JsonIgnore] to have Newtonsoft ignore this property and prevent the “self referencing loop” exception:
using Newtonsoft.Json;
public class Child
{
public string Name { get; set; }
[JsonIgnore]
public Parent Mom { get; set; }
}
Code language: C# (cs)
The resulting JSON looks like this:
{
"Name": "Mary",
"Children": [
{
"Name": "Barry"
}
]
}
Code language: JSON / JSON with Comments (json)
It’s common to add back reference properties to create a two-way link between objects. The problem is this, this creates a circular reference, which causes problems during serialization. Whenever you add properties like, I suggest adding [JsonIgnore].
Option 3 – Remove the property with the circular reference
If you accidently added a circular reference, then the “self referencing loop” exception points out this mistake to you. In this case, you can simply remove the property with the circular reference. In this example, I removed the Child.Parent property:
public class Child
{
public string Name { get; set; }
}
Code language: C# (cs)
Now serializing the Parent results in the following JSON:
{
"Name": "Mary",
"Children": [
{
"Name": "Barry"
}
]
}
Code language: JSON / JSON with Comments (json)
Since the Child object no longer has a reference to the Parent object, the “self referencing loop” problem is a non-issue. This is the best option if you really didn’t need the property to begin with. Use one of the other options above if you actually want to keep the property.