Serializing circular reference with a maxDepth results in a StackOverflow

Hello,

I’m trying to serialize the first level of a tree structure and I got a StackOverflow exception. I found a post where you suggest using JsConfig.MaxDepth to work around this issue however it did not solve my issue. I know that serializing this type of structure is not recommended but I cannot change the object.

Am I using MaxDepth correctly? I included below some code that mimic my production code which has issue.

    public class CircularRef
    {
        public CircularRef(string name)
        {
            Name = name;
        }

        public string Name { get; set; }
        public CircularRef Parent { get; set; }
    }

    public class CircularRefGroup : CircularRef
    {
        public CircularRefGroup(string name) : base(name) {}
        public List<CircularRefGroup> Children { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            CircularRefGroup circularRef0 = new CircularRefGroup("0");
            CircularRefGroup circularRef1 = new CircularRefGroup("1");

            circularRef0.Children = new List<CircularRefGroup>();
            circularRef0.Children.Add(circularRef1);
            circularRef1.Parent = circularRef0;

            JsConfig.MaxDepth = 1;
            JsConfig.IncludeTypeInfo = true;
            var serializedCircularRef = JsonSerializer.SerializeToString(circularRef0);
        }
    }

MaxDepth would only help for circular references of different types, not on the same type - models with circular refs shouldn’t be serialized at all, but you should be able to use BinaryFormatter for this if you must, but I wouldn’t as you’re always going to be running into issues, so I wouldn’t have this model at all, but if I absolutely needed it I’d map it to a DTO without circular refs that can be serialized cleanly in all serializers.

Otherwise an alternative is to ignore the property or change it to a method/private field so it won’t try to serialized it, if you don’t have control over the type you can try adding an attribute at runtime, e.g:

typeof(CircularRef)
    .GetProperty("Parent")
    .AddAttribute(typeof(IgnoreDataMemberAttribute));