mimo
mimo

Reputation: 6817

Handling circular reference with Newtonsoft JSON

My model class look like follows:

public class ModelType
{
    public string Name { get; set; }
    public ModelType SuperType { get; set }
    public IEnumerable<ModelType> SubTypes { get; set; }
}

I am trying to serialize object, but getting StackOverflowException. I have tried to call

JsonConvert.SerializeObject(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

as well as

JsonConvert.SerializeObject(model, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });

Both calls resulted in StackOverflowException. Any idea how to serialize ModelType instance?

EDIT:

Example of instance, which fails to serialize:

{
    Name: "Child",
    SuperType: {
        Name: "Parent",
        SuperType: null,
        SubTypes: [{
                Name: "Child",
                SuperType: {
                    Name: "Parent",
                    SuperType: null,
                    SubTypes: [{Name: "Child", ...}]
                },
                SubTypes: []
        }]
    },
    SubTypes: []
}

EDIT2:

By further looking into the issue (according to all SO Q&A, setting either ReferenceLoopHandling.Ignore or PreserveReferencesHandling.Objects should work) I have found out that

  1. Child is unique object instance
  2. Child.SuperType (Parent) is unique object instance
  3. Child.SuperType.SubTypes[0] (Child) is unique object instance, not a reference to (1.)
  4. Child.SuperType.SubTypes[0].SuperType (Parent) is unique object instance, not a reference to (2.)
  5. And so on...

I think, something went wrong during the object creation (out of my code) and this created infinite chain of objects. I am not sure if this is even possible to handle just by JsonSerializerSettings.

Upvotes: 9

Views: 25798

Answers (1)

Avi Fatal
Avi Fatal

Reputation: 1558

Newtonsoft.Json can have the following config

 JsonSerializerSettings sets = new JsonSerializerSettings
    {
        PreserveReferencesHandling = PreserveReferencesHandling.Objects
    };

    var ser = JsonSerializer.Create(sets);

you might want to do that.

Upvotes: 8

Related Questions