0

I am trying to serialize and deserialize inheriting objects in a dictionary using JSON.net NewtonSoft.

In my program I have 3 classes setup A, B and C. Both B and C inherit A:

public class A
{
    public virtual string Value { get; } = "string";
}


public class B : A
{
    public override string Value => this.Score.ToString();

    public int Score { get; set; } = 5;
}

public class C : A
{
    public override string Value => this.AnotherScore.ToString();

    public int AnotherScore { get; set; } = 6;
}

In my code I create a dictionary which can story objects inheriting A and fill it with a B and a C object.

When I try using the objects in the dictionary, C# still knows the objects are of their type. (see code below)

But after serializing and deserializing, C# doesn't understand that it has to treat the B and C object in the dictionary as B and C objects.

static void Main(string[] args)
{
    // Create objects to store in dictionary
    B b = new B();
    A c = (A)new C(); 

    // Store objects in dictionary
    var dic = new Dictionary<string, A>();
    dic.Add("b", b);
    dic.Add("c", c);

    // C# still know the objects are of their type
    Console.WriteLine(dic["b"].Value);
    Console.WriteLine(dic["c"].Value);

    // Convert dictionary to JSON
    string serialized = JsonConvert.SerializeObject(dic, new JsonSerializerSettings()
    {
        Formatting = Formatting.Indented,
        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
        TypeNameHandling = TypeNameHandling.Objects,
    });

    Console.WriteLine(serialized);

    // Convert json to dictionary
    var dic2 = JsonConvert.DeserializeObject<Dictionary<string, A>>(serialized);

    // C# doesn't know objects are of their type anymore
    Console.WriteLine(dic2["b"].Value);
    Console.WriteLine(dic2["c"].Value);




    Console.ReadKey();
}

Output:

5
6
{
  "$id": "1",
  "$type": "System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[TestConsole.A, TestConsole]], mscorlib",
  "b": {
    "$id": "2",
    "$type": "TestConsole.B, TestConsole",
    "Value": "5",
    "Score": 5
  },
  "c": {
    "$id": "3",
    "$type": "TestConsole.C, TestConsole",
    "Value": "6",
    "AnotherScore": 6
  }
}
string
string

How do I let NewtonSoft know it should serialize the objects correctly with their correct type?

So that the last two write lines will write the same as the first two.

3
  • 3
    You have to use the same TypeNameHandling settings for the deserializer too, i guess... Commented Mar 20, 2018 at 22:39
  • @elgonzo Yeah noticed that right after posting the question, thanks for the help! Commented Mar 20, 2018 at 22:42
  • Possible duplicate of how to deserialize JSON into IEnumerable<BaseType> with Newtonsoft JSON.NET Commented Mar 20, 2018 at 22:42

1 Answer 1

2

Passing the same settings to the DesirializeObject will solve this issue.

Sorry for bothering.

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

Comments

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.