1

I have the following classes:

public class Base
{
}

public class A : Base
{
    public Base AField { get; set; }
}

public class B : Base
{
    public int I { get; set; }
    public int I2 { get; set; }
}

I want to serialize all Base objects (using newtonsoft json) so I can store extra data plus the normal properties of the child class, but in a nested object. So if I was serializing an instance of A, I would get something like this:

{
  "Extra1": 1,
  "Extra2": 2,
  "Data": {
    "AField": {
      "Extra1": 1,
      "Extra2": 2,
      "Data": {
        "I": 12345,
        "I2": 6789
      }
    }
  }
}

So far I wrote this converter:

public class BaseConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var token = JToken.FromObject(value);
        var obj = new JObject
        {
            ["Extra1"] = 1,
            ["Extra2"] = 2, // etc
            ["Data"] = token
        };
        obj.WriteTo(writer);
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsSubclassOf(typeof(Base)) || objectType == typeof(Base);
    }
}

It works fine when serializing an instance of B. But it doesn't work recursively. I mean when I try to serialize an instance of A, I expect to get

{
  "Extra1": 1,
  "Extra2": 2,
  "Data": {
    "AField": {
      "Extra1": 1,
      "Extra2": 2,
      "Data": {
        "I": 12345,
        "I2": 6789
      }
    }
  }
}

but I actually get

{
  "Extra1": 1,
  "Extra2": 2,
  "Data": {
    "AField": {
      "I": 12345,
      "I2": 6789
    }
  }
}

which is like the converter didn't even run for AField. But when I look in the debugger the writejson function is indeed called for AField. What could be the problem here? Thanks in advance.

xnsc
  • 126
  • 1
  • 6
  • Presumably you are adding the converter to `JsonSerializerSettings.Converters`. Is that correct? Then the problem is that when you call `JToken.FromObject(value);` that converter is not passed in, so it's not called recursively. But if you do pass it in, you will get a stack overflow. – dbc Mar 22 '23 at 05:02
  • 1
    What I think should work for you is `JsonExtensions.DefaultFromObject(this JsonSerializer serializer, object value)` from the *second, simpler workaround* in [this answer](https://stackoverflow.com/a/29720068/3744182) to [JSON.Net throws StackOverflowException when using `[JsonConvert()]`](https://stackoverflow.com/q/29719509/3744182). Can you confirm? – dbc Mar 22 '23 at 05:02

0 Answers0