Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NewtonSoft.json base class serialization

Tags:

json

c#

.net

wpf

When I updated the concerned Newtonsoft.json.dll from .NET 3.5 to .NET 4.5 then base class is not Serializing. Before updating, the base class was serializing.

public class MyBaseClass
{
    public string BaseProp1 { get; set; }
    public string BaseProp2 { get; set; }
}

[DataContract]
public class MyDerivedClass : MyBaseClass
{
    [DataMember]
    public DateTime DerProp1 { get; set; }
    public string DerProp2 { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        MyDerivedClass derc = new MyDerivedClass();
        derc.BaseProp1 = "BaseProp1";
        derc.DerProp1 = DateTime.Now;
        derc.BaseProp2 = "BaseProp2";
        derc.DerProp2 = "DerProp2";

        Newtonsoft.Json.Converters.IsoDateTimeConverter conv = new Newtonsoft.Json.Converters.IsoDateTimeConverter();
        conv.DateTimeFormat = "MM/dd/yyyy HH:mm:ss zzz";

        string jsonSerializedObject = JsonConvert.SerializeObject(derc, conv);

    }
}

The program does not serialize members of the base class. The reason for that is that I have not specified the [DataContract] in the base class. I need ALL the members to be serialized. Problems:

  1. I can not remove [DataContract] from the derived class as it is extensively used by WCF.
  2. I do not want to add [DataContract] to the base class as there are a LOT of members.

What is the best way to go ahead?

like image 387
Ankit Jain Avatar asked Feb 10 '23 21:02

Ankit Jain


1 Answers

The base class properties are ignored by default. You can change this behavior by creating a custom contract resolver.

class MyContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var list = base.CreateProperties(type, memberSerialization);

        foreach (var prop in list)
        {
            prop.Ignored = false; // Don't ignore any property
        }

        return list;
    }
}

This resolver will effectively make sure that no properties are ignored. You might want to apply some logic if you do want to ignore some properties.

To use the resolver; create a JsonSerializerSettings instance and supply that to the JsonConvert.SerializeObject method.

Your last line would be replaced by:

JsonSerializerSettings settings = new JsonSerializerSettings
{
    ContractResolver = new MyContractResolver(),
    Converters = { conv },
};

string jsonSerializedObject = JsonConvert.SerializeObject(derc, settings);

Base class properties would then be serialized:

{
"DerProp1":"02-17-2015 13:39:29 +01:00",
"DerProp2":"DerProp2",
"BaseProp1":"BaseProp1",
"BaseProp2":"BaseProp2"
}
like image 51
Mårten Wikström Avatar answered Feb 13 '23 21:02

Mårten Wikström