Search code examples
c#json-deserializationsystem.text.json

Serializing data to json with multiple circular dependencies


I'm working on some code that serializes and deserializes a complex data structure.

I have a data model in C# consisting of three classes: TypeA, TypeB, and TypeC. TypeA has a reference to TypeB, TypeB has a reference to TypeA, and TypeC has references to two instances of TypeB.

When attempting to serialize these objects using System.Text.Json, I encounter issues due to the circular dependencies.

Here's a simplified version of my code:

using System;
using System.Collections.Generic;
using System.Text.Json;

public class TypeA
{
    public int Id { get; set; }
    public string Name { get; set; }
    public TypeB LinkedB { get; set; }
}

public class TypeB
{
    public int Id { get; set; }
    public string Description { get; set; }
    public TypeA LinkedA { get; set; }
}

public class TypeC
{
    public int Id { get; set; }
    public string Note { get; set; }
    public TypeB Reference1 { get; set; }
    public TypeB Reference2 { get; set; }
}

public class ObjectToSerialize
{
    public List<TypeA> Data { get; set; }

    public List<TypeC> links { get; set; }
}

I don't really care about what the serialized data looks like because I'm going to deserialize it back into the same data model with the same code.

I've already looked at RefrenceHandler, but I feel like that only solves one of the two references and not both. (Correct me if I'm wrong)

I'm looking for a solution to serialize these objects using System.Text.Json so that the original references stay intact.

How can I achieve this while staying close to the original data model and the default way System.Text.Json serializes objects? I'm open to writing custom converters, modifying the data model, or using a different serialization library if necessary.

Any insights or workarounds would be greatly appreciated.

Thank you!


Solution

  • Please try the example below and let me know if that fixed your issue:

            var typeA = new TypeA
            {
                Id = 1,
                Name = "Name",
            };
    
            var typeBFirst = new TypeB
            {
                Id = 1,
                Description = "Description 1",
                LinkedA = typeA
            };
    
            typeA.LinkedB = typeBFirst;
    
            var typeBSecond = new TypeB
            {
                Id = 2,
                Description = "Description 2",
                LinkedA = typeA
            };
    
            var typeC = new TypeC
            {
                Id = 1,
                Note = "Note",
                Reference1 = typeBFirst,
                Reference2 = typeBSecond
            };
    
            JsonSerializerOptions options = new()
            {
                ReferenceHandler = ReferenceHandler.Preserve,
                WriteIndented = true
            };
    
            var result = JsonSerializer.Serialize(typeC, options);
    

    You can read more here How to preserve references and handle or ignore circular references in System.Text.Json