c# json json.net

c# - Diccionario de objetos serialización/deserialización con JSON.NET



(1)

Estoy tratando de serializar / deserializar un Dictionary<string, object> que parece funcionar bien si el objeto es un tipo simple pero no funciona cuando el objeto es más complejo.

Tengo esta clase:

public class UrlStatus { public int Status { get; set; } public string Url { get; set; } }

En mi diccionario, agrego una List<UrlStatus> con una clave de "Redirigir cadena" y algunas cadenas simples con las teclas "Estado", "Url", "Url principal". La cadena que estoy obteniendo de JSON.Net se ve así:

{"$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"}]}

El código que estoy usando para serializar se ve así:

JsonConvert.SerializeObject(collection, Formatting.None, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple });

deserializar lo estoy haciendo:

JsonConvert.DeserializeObject<T>(collection, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple, });

El diccionario vuelve bien, todas las cadenas vuelven bien, pero la Lista no se deserializa adecuadamente. Simplemente vuelve como

{[ { "$type": "XYZ.TestFramework.Core.Entities.UrlStatus, XYZ.TestFramework.Core", "Status": 301, "Url": "/how_5615409_create-pdfs-using-bean.html" } ]}

Por supuesto, puedo deserailizar esta cadena nuevamente y obtengo el objeto correcto, pero parece que JSON.Net debería haber hecho esto por mí. Claramente estoy haciendo algo mal, pero no sé lo que es.


Creo que es un error en una versión anterior de Json.NET. Si aún no está utilizando la última versión, actualícela y vuelva a intentarlo.

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); } }

Editar, acabo de notar que mencionaste una lista. TypeNameHandling debe establecerse en Todo.

Documentación: configuración de TypeNameHandling