I'm trying to serialize/deserialize a Dictionary<string, object>
which seems to work fine if the object is a simple type but doesn't work when the object is more complex.
I have this class:
public class UrlStatus { public int Status { get; set; } public string Url { get; set; } }
In my dictionary I add a List<UrlStatus>
with a key of "Redirect Chain" and a few simple strings with keys "Status", "Url", "Parent Url". The string I'm getting back from JSON.Net looks like this:
{"$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib","Status":"OK","Url":"http://www.ehow.com/m/how_5615409_create-pdfs-using-bean.html","Parent Url":"http://www.ehow.com/mobilearticle35.xml","Redirect Chain":[{"$type":"Demand.TestFramework.Core.Entities.UrlStatus, Demand.TestFramework.Core","Status":301,"Url":"http://www.ehow.com/how_5615409_create-pdfs-using-bean.html"}]}
The code I'm using to serialize looks like:
JsonConvert.SerializeObject(collection, Formatting.None, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple });
to deserialize I'm doing:
JsonConvert.DeserializeObject<T>(collection, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple, });
The Dictionary comes back fine, all the strings come back fine, but the List doesn't get properly deserialized. It just comes back as
{[ { "$type": "XYZ.TestFramework.Core.Entities.UrlStatus, XYZ.TestFramework.Core", "Status": 301, "Url": "/how_5615409_create-pdfs-using-bean.html" } ]}
Of course I can deserailize this string again and I get the correct object, but it seems like JSON.Net should have done this for me. Clearly I'm doing something wrong, but I don't know what it is.
JSON is a format that encodes objects in a string. Serialization means to convert an object into that string, and deserialization is its inverse operation (convert string -> object).
Json can't serialize Dictionary unless it has a string key. The built-in JSON serializer in . NET Core can't handle serializing a dictionary unless it has a string key.
Introducing JSON JSON is a way of representing Arrays and Dictionaries of values ( String , Int , Float , Double ) as a text file. In a JSON file, Arrays are denoted by [ ] and dictionaries are denoted by { } .
Simple One-Line Answer This code will convert any Dictionary<Key,Value> to Dictionary<string,string> and then serialize it as a JSON string: var json = new JavaScriptSerializer(). Serialize(yourDictionary. ToDictionary(item => item.
I think that is a bug in an older version of Json.NET. If you aren't already using the latest version, upgrade and try again.
public class UrlStatus { public int Status { get; set; } public string Url { get; set; } } [TestMethod] public void GenericDictionaryObject() { Dictionary<string, object> collection = new Dictionary<string, object>() { {"First", new UrlStatus{ Status = 404, Url = @"http://www.bing.com"}}, {"Second", new UrlStatus{Status = 400, Url = @"http://www.google.com"}}, {"List", new List<UrlStatus> { new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"}, new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"} } } }; string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple }); Assert.AreEqual(@"{ ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"", ""First"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"", ""Status"": 404, ""Url"": ""http://www.bing.com"" }, ""Second"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"", ""Status"": 400, ""Url"": ""http://www.google.com"" }, ""List"": { ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests]], mscorlib"", ""$values"": [ { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"", ""Status"": 300, ""Url"": ""http://www.yahoo.com"" }, { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TypeNameHandlingTests+UrlStatus, Newtonsoft.Json.Tests"", ""Status"": 200, ""Url"": ""http://www.askjeeves.com"" } ] } }", json); object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple }); Assert.IsInstanceOfType(c, typeof(Dictionary<string, object>)); Dictionary<string, object> newCollection = (Dictionary<string, object>)c; Assert.AreEqual(3, newCollection.Count); Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url); List<UrlStatus> statues = (List<UrlStatus>) newCollection["List"]; Assert.AreEqual(2, statues.Count); } }
Edit, I just noticed you mentioned a list. TypeNameHandling should be set to All.
Documentation: TypeNameHandling setting
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With