-1

Suppose the following dummy example

internal abstract class Individual
{
    public string Name { get; set; }
    public abstract bool IsMammal { get; }
}

internal class Human : Individual
{
    public override bool IsMammal => true;
    // other properties...
}

internal class Eagle : Individual
{
    public override bool IsMammal => false;
    // other properties...
}

and that we have a habitat that we want to serialize.

internal class Habitat
{
    public List<Individual> Inhabitants;
}

Now, for all those Individuals where IsMammal == true, I want the full object to be serialized. But for those individuals where IsMammal == false, I would like to simply write the name. Such that the list Inhabitants

Inhabitants = new List<Individual> { new Human { Name = "Frank" }, new Eagle { Name = "Brucie" } };

Would be serialized to JSON as following

{
  Inhabitants = [
    {
      Name = "Frank",
      // Other properties
    },
    "Brucie"
  ]
}

We have been looking a lot in the documentation of Newtonsoft and trying out stuff with ContractResolver's and/or CustomConverter's but we cannot get it to work. The documentation and online resources talk about how to serialize a specific class but never conditionally on a property. We for example already tried

class IndividualJsonConverter: JsonConverter<Individual> 
{
    public override void WriteJson(JsonWriter writer, Individual value, JsonSerializer serializer)
    {
        if (!value.IsMammal)
        {
          // TODO > Write away name only.
        }
        else
        {
          base.WriteJson(writer, value, serializer);
        }
    }
}

But there is no such thing as base.WriteJson as this is abstract.

  • Newtonsoft doesn't have a straightforward way to generate a "default" serialization from inside a JsonConverter. For some options see [JSON.Net throws StackOverflowException when using `[JsonConvert()]`](https://stackoverflow.com/q/29719509/3744182). In fact that may be a duplicate, agree? – dbc Jun 28 '22 at 13:45
  • your json Name = "Frank", is not valid – Serge Jun 28 '22 at 19:39

1 Answers1

0

I don't like any fansy custom converters and serializers. IMHO this code is much clear

    var jsonObj=new JObject();
    var jArray=new JArray();
    
    jsonObj.Add("Inhabitans",jArray);
    
    foreach (var item in inhabitants )
    {
        if (item.IsMammal) jArray.Add(JObject.FromObject(item));
        else jArray.Add(item.Name);
    }
    
    var json=jsonObj.ToString();

json

{
  "Inhabitans": [
    {
      "IsMammal": true,
      "Name": "Frank"
    },
    "Brucie"
  ]
}
Serge
  • 40,935
  • 4
  • 18
  • 45