Repository navigation
Description
Object/collection graphs containing circular references (or multiple references to the same entity), can be handled in a few different ways when serializing/deserializing to/from JSON.
Best practice is naturally to avoid graphs with circular references when using JSON serialization, but techniques to deal with it exist, and some times it may be needed. We use it a few places in our software.
NewtonSoft.Json supports this, and I guess it is a goal for System.Text.Json to make the feature gap with NewtonSoft as small possible.
During serialization, when an object/collection that has already been serialized is referenced for the second time or more, the common technique I've seen is to replace the repeated objects/collection in the JSON with a
{ "$ref": "some-sort-of-pointer" }Some use JSONPath to reference the object/array serialized previously in the JSON document.
NewtonSoft.Json uses a different techique with specific serialization settings: It adds an extra "$id" property to all serialized objects in the JSON document, and the "$ref" value is the "$id" property of the object/array serialized previously.
Example using NewtonSoft.Json:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace CircularSerialization
{
public class Bike
{
public List<Tire> Tires { get; set; } = new List<Tire>();
}
public class Tire
{
public Bike Bike { get; set; }
}
static class Program
{
static void Main()
{
var bike = new Bike();
bike.Tires.Add(new Tire { Bike = bike });
bike.Tires.Add(new Tire { Bike = bike });
var settings = new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var serialized = JsonConvert.SerializeObject(bike, settings);
Console.Write(serialized);
// {"$id":"1","Tires":[{"$id":"2","Bike":{"$ref":"1"}},{"$id":"3","Bike":{"$ref":"1"}}]}
}
}
}I guess that if System.Text.Json.JsonSerializer will support circular/multiple references, some more memory allocation will be required during serialization/deserialization when the setting is switched on (so such a setting should naturally be off by default).
Is there a plan to support options for handling circular references in JsonSerializerSettings?
And if so, will you support the "$id" technique or the JSONPath techique, or maybe support both?
Reference:
https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
Activity
ahsonkhan commentedon Aug 5, 2019
Thanks for filing the issue, @josundt
However, this is a duplicate of https://github.com/dotnet/corefx/issues/38579.
It is on our backlog of features to support for vNext.
I have added your example there instead. Closing.
jozkee commentedon Jan 21, 2020
The preview version for
ReferenceHandlingfeature is here.Download the
System.Text.Jsonpreview package version5.0.0-alpha.1.20071.1from dotnet5 gallery (through Visual Studio's NuGet client):https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json
How to use it:
Set
ReferenceHandling.PreservetoReferenceHandlingproperty inJsonSerializerOptions.Here's the spec doc including samples and notes about many scenarios.
If you want to add feedback, feel free to leave a comment in https://github.com/dotnet/corefx/issues/41002.