mgholam / fastJSON

Smallest, fastest polymorphic JSON serializer
https://www.codeproject.com/Articles/159450/fastJSON-Smallest-Fastest-Polymorphic-JSON-Seriali
MIT License
478 stars 148 forks source link

A class with an object property storing a Dictionary<string, string> doesn't deserialize properly #139

Open ignusfast opened 2 years ago

ignusfast commented 2 years ago

I have a simple class with an object property. If I store a Dictionary<string, string> in that property and serialize/deserialize the class, the Dictionary comes back as a Dictionary<string, object>. Because I'm expecting the former, my cast fails and nothing works. I assume this is because no types are being embedded for the Dictionary, but I need a way to override this, if possible.

I have a class that contains an object called Response. public class DataCacheResponse { public DataCacheResponse();

   public string LastError { get; set; }
   public object Response { get; set; }

}

In Response, I’m sending a Dictionary<string, string>. When I serialize it as below, you can see the Dictionary values look correct, but there’s no type information at all. { "$types": { "MainAssembly.DataCacheResponse, MainAssembly, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b2997cac92e35e61": "1" }, "$type": "1", "LastError": "", "Response": { "poo": "poop", "pee": "peep" } }

Here’s the test code: var rq3 = new DataCacheResponse() { LastError = string.Empty, Response = new Dictionary<string, string>() { { "poo", "poop" }, { "pee", "peep" } } }; var js3 = rq3.ToTypedJson(); Console.WriteLine($"Json: {js3}"); var r23 = js3.FromTypedJson(); Console.WriteLine($"Object: {r23.LastError} - {((Dictionary<string, string>)r23.Response)["poo"]}");

So when I deserialize the above, the deserialization works, but the Dictionary<string, string> is actually being deserialized as a Dictionary<string, object>. So in that last line, when I try to cast it to Dictionary<string, string> it fails. System.InvalidCastException HResult=0x80004002 Message=Unable to cast object of type 'System.Collections.Generic.Dictionary2[System.String,System.Object]' to type 'System.Collections.Generic.Dictionary2[System.String,System.String]'. Source=TestValidation

If I instead do this, it works, but this is far less than desirable… Console.WriteLine($"Object: {r23.LastError} - {((Dictionary<string, object>)r23.Response)["poo"]}");