9

I am using Newtonsoft JSON serializer, and the serialized string is missing the properties from the derived class if the class is derived from a list. Here is my example code.

Classes:

[DataContract]
public class TestItem
{
    [DataMember]
    public int itemInt;
    [DataMember]
    public string itemString;

    public TestItem() {}
    public TestItem(int _intVal, string _stringVal)
    {
        itemInt = _intVal;
        itemString = _stringVal;
    }
}

[DataContract]
public class TestMain : List<TestItem>
{
    [DataMember]
    public int mainInt;
    [DataMember]
    public string mainString;
}

Serializing code:

string test;

// Test classes
TestMain main = new TestMain();
main.mainInt = 123;
main.mainString = "Hello";
main.Add(new TestItem(1, "First"));

test = Newtonsoft.Json.JsonConvert.SerializeObject(main);

After serialization, the value of test is:

[{\"itemInt\":1,\"itemString\":\"First\"}]

The values for mainInt and mainString are missing altogether.

The behaviour is not changed by the [DataContract] and [DataMember] tags, but I have them in there, to pre-empt the answer that they are missing.

How do I get JSON to recognize and serialize the mainInt and mainString properties of the derived class?

3 Answers 3

1

Take a look at putting json attribs on your properties. Here is a sample: Json.NET serialize object with root name. The only thing I would hesitate to do is having the main derive from list like that. Its not a recommended pattern and practice. add list as another child property rather then deriving from list, json serialize is getting confused as to your intentions.

Sign up to request clarification or add additional context in comments.

2 Comments

Good idea, but still doesn't work. Once I tag TestMain as a JsonObject, the mainInt and mainString come through, but the list items do not!
Having the list as a property of TestMain would be a solution (JSON works fine with that), but unfortunately that will affect other code that we have no control over - there is 3rd party code that uses these classes as they are, derived from a List<>.
1

Is this what you want?

[DataContract]
public class TestItem
{
    [DataMember]
    public int itemInt { get; set; }
    [DataMember]
    public string itemString { get; set; }

    public TestItem() { }
    public TestItem(int _intVal, string _stringVal)
    {
        itemInt = _intVal;
        itemString = _stringVal;
    }
}

[DataContract]
public class TestMain
{
    [DataMember]
    public int mainInt { get; set; }
    [DataMember]
    public string mainString { get; set; }
    [DataMember]
    public List<TestItem> TestItem = new List<TestItem>();
}

class Program
{
    static void Main(string[] args)
    {
        string test;

        // Test classes
        TestMain main = new TestMain();
        main.mainInt = 123;
        main.mainString = "Hello";
        main.TestItem.Add(new TestItem(1, "First"));
        test = Newtonsoft.Json.JsonConvert.SerializeObject(main);
        Console.WriteLine(test);
    }
}

3 Comments

This would solve the JSON problem, but unfortunately we can't do this. Existing 3rd party code uses the TestMain class, so the TestMain class cannot be modified to have the list as a property. TestMain has to remain as derived from List<TestItem>.
So you can modify TestItem class?
No, we can't modify any of the classes. :(
1

adding this attrib works for me:

using System.ComponentModel.DataAnnotations;

[Newtonsoft.Json.JsonObject(Title = "root")] public class Testmain : List

1 Comment

Thanks, [JsonObject] worked for me to get a derived class to be serialized. But it serialized everything even things in the base class that weren't originally serialized, so instead [JsonProperty] on the properties that were missing worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.