skip to Main Content

Given:

class Mammal
{
    public int Age { get; set; }
}

class Human : Mammal
{
    public string Name { get; set; }
}

class Stuff
{
    public Mammal Mammal { get; set; }
}

And

var stuff = new Stuff
{
    Mammal = new Human
    {
        Name = "test",
        Age = 12
    }
};

Console.WriteLine(JsonConvert.SerializeObject(stuff));

I get:

{"Mammal":{"Name":"test","Age":12}}

But I only want to get properties defined in type statically (meaning that I shouldn’t see the name in the JSON), not runtime-type properties. How to do that?

2

Answers


  1. Use [JsonIgnore]:

    class Human : Mammal
    {
        [JsonIgnore] public string Name { get; set; }
    }
    

    This will print:

    {"Mammal":{"Age":12}}
    
    Login or Signup to reply.
  2. You can try extending DefaultContractResolver:

    public class MyContractResolver : DefaultContractResolver
    {
        protected override JsonContract CreateContract(Type objectType)
        {
            // Of course, the logic here is up to you!
            if (objectType == typeof(Human))
            {
                return base.CreateContract(typeof(Mammal)); 
            }
            return base.CreateContract(objectType);
        }
    }
    

    It simply says – if the object serialized is of type Human, serialize it accordingly to the contract of the base class Mammal. Which is exactly what you want. This then should be used like this:

    var stuff = new Stuff
    {
        Mammal = new Human
        {
            Name = "test",
            Age = 12
        }
    };
    
    var json = JsonConvert.SerializeObject(
        stuff,
        Formatting.Indented,
        new JsonSerializerSettings 
        { 
            ContractResolver = new MyContractResolver() 
        });
    

    Reference: Contract Resolvers

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search