2010-09-17 20 views
34

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

tengo esta clase:

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

En mi diccionario agrego un List<UrlStatus> con una clave de "cadena de redirección" y algunas cadenas simples con las teclas "Estado", "URL", "URL de Padres" . La cadena que estoy de volver 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 el siguiente aspecto:

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

deserializar que estoy haciendo:

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

el Diccionario vuelve fina, todas las cadenas vuelven muy bien, pero la lista no quede adecuadamente deserializan. Sólo regresa como

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

Por supuesto que puedo deserailize esta cadena de nuevo y me sale 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.

Respuesta

43

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


    [Test] 
    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(typeof(Dictionary<string, object>), c); 

     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, Me acabo de dar cuenta de que usted mencionó una lista. TypeNameHandling debe establecerse en Todo.

Documentación: TypeNameHandling setting

+1

estoy usando Json.NET 3.5 Release 8. incluso he descargado el zip de nuevo para estar seguro. –

+0

Acabo de probar la última compilación 53965, todavía no funcionó. –

+6

TypeNameHandling = TypeNameHandling.All fue el truco. –