To preserve references and handle circular references, set ReferenceHandler
to Preserve
. This setting causes the following behavior:
$id
, $values
, and $ref
).The following code shows the usage of the Preserve
setting.
public class Employee
{
public string Name { get; set; }
public Employee Manager { get; set; }
public List<Employee> DirectReports { get; set; }
}
public static void Example()
{
Employee tyler = new()
{
Name = "Tyler Stein"
};
Employee adrian = new()
{
Name = "Adrian King"
};
tyler.DirectReports = new List<Employee> { adrian };
adrian.Manager = tyler;
JsonSerializerOptions options = new()
{
ReferenceHandler = ReferenceHandler.Preserve,
WriteIndented = true
};
string tylerJson = JsonSerializer.Serialize(tyler, options);
Console.WriteLine($"Tyler serialized:\n{tylerJson}");
Employee tylerDeserialized = JsonSerializer.Deserialize<Employee>(tylerJson, options);
Console.WriteLine("Tyler is manager of Tyler's first direct report: ");
Console.WriteLine(tylerDeserialized.DirectReports[0].Manager == tylerDeserialized);
}
The above example will print the following output.
Tyler serialized:
{
"$id": "1",
"Name": "Tyler Stein",
"Manager": null,
"DirectReports": {
"$id": "2",
"$values": [
{
"$id": "3",
"Name": "Adrian King",
"Manager": {
"$ref": "1"
},
"DirectReports": null
}
]
}
}
Tyler is the manager of Tyler's first direct report:
True
You can not use this feature to preserve value types or immutable types. On deserialization, the instance of an immutable type is created after the entire payload is read.
$ref
or $id
is found.$id
(and $values in the case of collections) to make it possible to deserialize payloads that were serialized by using Newtonsoft.Json
.To determine if objects are equal, System.Text.Json
uses ReferenceEqualityComparer.Instance
, which uses reference equality (Object.ReferenceEquals(Object, Object))
instead of value equality (Object.Equals(Object)
when comparing two object instances.
For more information about how references are serialized and deserialized, see ReferenceHandler.Preserve.
The ReferenceResolver class defines the behavior of preserving references on serialization and deserialization.