First thing that comes to mind are circular dependencies.
Let's say we have a class that has a field referencing its child, and the child class has a field referencing its parent.
public class A
{
public B Child;
}
public class B
{
public A Parent;
}
public class Program
{
private static void Main()
{
A a = new A();
B b = new B();
a.Child = b;
b.Parent = a;
string json = JsonConvert.SerializeObject(a);
}
}
This would cause a run-time JsonSerializationException
at JsonConvert.SerializeObject(a)
with the following message:
Self referencing loop detected for property 'Parent' with type 'A'. Path 'Child'.
To avoid this, JSON.NET provides an overload of SerializeObject
to pass a settings object, where we can specifiy how to handle circular references.
JsonSerializerSettings settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.None,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
JsonConvert.SerializeObject(a, settings);
This way, the output json would completely ignore the circular reference from the child to the parent, and it would look like this:
{
"Child": {}
}
JSON.NET also provides a way to handle them without losing information. We'd need to specifiy the option PreserveReferencesHandling.Objects
in the settings.
JsonSerializerSettings settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
The output JSON can only be interpreted by JSON.NET or other serializers compatible with the $id
and $ref
syntax, and it will look like this:
{
"$id":"1",
"Child": {
"$id":"2",
"Parent": {
"$ref":"1"
}
}
}