0

Here is my situation. We are at the junction to decide what Json serialization tool to use. we are considering Newtonsoft.JSON and Microsoft JavaScriptSerializer. Newtonsoft.JSON has been our first peek, but we stumble over peculiar behaviour. Here is schematic code to ilustrate the problem. Let say we have following disposition of classes:

interface IA<T>
{
    T Id { get; set; }
}

[DataContractAttribute]
abstract class A : IA<string>
{
    protected A() { }

    [DataMemberAttribute]
    public virtual  string Id
    {
        get;
        set;
    }
}
class B : A
{
    public string P1 { get; set; }
    public string P2 { get; set; }
}

Then if we will utilize Newtonsoft.Json's JsonConvert class to get JSON string out of the B class we could use following code:

        B b = new B();
        string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b, 
            new Newtonsoft.Json.JsonSerializerSettings() { 
                NullValueHandling = Newtonsoft.Json.NullValueHandling.Include 
            });

But unfortunately only Id property would be reflected in the resulting JSON string. All other properties of the B class would not show up. Contrary, JavaScriptSerializer produces JSON string as expected though. Class B is our class, class A and interface IA are from 3rd party library so we could not modify them. Also we don't want to use data contract serialization annotation on our classes either just to appease picky json serializer.

Is there any way to instruct Newtonsoft.Json.JsonConvert to serialize all properties regardless annotated or not?

EDIT: Though @LB provided acceptable answer @dbc came up with more comprehensive solution, so if you wanna see it just following to the link he provided as duplication for this question.

fatherOfWine
  • 1,191
  • 16
  • 39
  • As my question stated:"class A and interface IA are from 3rd party library so we could not modify them". So this is not the option for us, unfortunately. – fatherOfWine Sep 02 '16 at 19:22
  • Similar question: [Configure JSON.NET to ignore DataContract/DataMember attributes](https://stackoverflow.com/questions/11055225/configure-json-net-to-ignore-datacontract-datamember-attributes). – dbc Sep 02 '16 at 19:31
  • @dbc Thank you for the response I will check the link. – fatherOfWine Sep 02 '16 at 19:46
  • The contract resolvers in that solution are somewhat out of date for Json.NET 9.0.1. Maybe I should add another answer there? – dbc Sep 02 '16 at 19:50
  • @dbc Well, it depend. I am looking not for ignoring, but including all available properties. Basically to replicate what JavaScriptSerializer does: get the object list it's properties, serialize them. I've been puzzled, when I saw only Id property in the resulting JSON string. Why JSON.Net serializes only DataContract properties out of all class is a bit curious. If there is something we could do, to change default behavior, then please post the solution by all means! – fatherOfWine Sep 02 '16 at 19:59
  • The most-upvoted contract resolver solution apparently no longer works. The other contract resolver solutions work -- but further serialize properties explicitly marked with `[JsonIgnore]` which might not be desirable. – dbc Sep 02 '16 at 20:04
  • 1
    @dbc Thanks a lot, buddy! I was about to see if it will work! So basically if it could be put to work it should be custom contract resolver way, right? – fatherOfWine Sep 02 '16 at 20:11
  • Yes, a [custom contract resolver](http://www.newtonsoft.com/json/help/html/contractresolver.htm) is the way to go if you don't want to add additional attributes. – dbc Sep 02 '16 at 20:36

1 Answers1

4

You don't need DataContractAttributeand DataMemberAttributefor Json.Net . Remove them and your code will work....

Either use them for all properties or never use them

See http://www.newtonsoft.com/json/help/html/DataContractAndDataMember.htm

------ EDIT-------

If you don't wan't to use any Attributes then you can create a custom ContractResolver

public class MyDefaultContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var result = base.CreateProperties(type, memberSerialization).ToList();
        result.ForEach(x => { x.Ignored = false; }); // <-- Include or not? 
        return result;
    }
}

And serialize your code as:

string jsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(b,
new Newtonsoft.Json.JsonSerializerSettings()
{
    NullValueHandling = Newtonsoft.Json.NullValueHandling.Include,
    ContractResolver = new MyDefaultContractResolver()
});
L.B
  • 114,136
  • 19
  • 178
  • 224
  • 2
    As my question stated:"class A and interface IA are from 3rd party library so we could not modify them". So this is not the option for us, unfortunately. – fatherOfWine Sep 02 '16 at 19:23
  • 3
    @fatherOfWine Then just add `DataMember` attribute to `P1` and `P2` as I said.... It will work too... – L.B Sep 02 '16 at 19:24
  • @downvoter, I guess you don't want to explain your reason :) – L.B Sep 02 '16 at 19:28
  • 1
    @LB No, thank you. That's not the solution either, as it was also stated by the question. I am looking for the solution, that would not require annotating our classes. If that's could not be achieved with JSON.Net - so be it. If there is possibility, I would like to c it. – fatherOfWine Sep 02 '16 at 19:42
  • @fatherOfWine see the edit.... – L.B Sep 02 '16 at 20:19
  • @LB Your last edit is what I've been looking for. Thank you. – fatherOfWine Sep 06 '16 at 22:38