2010-09-17 5 views
34

Ich versuche, eine Dictionary<string, object> serialisieren/deserialisieren, die gut zu funktionieren scheint, wenn das Objekt ein einfacher Typ ist, aber nicht funktioniert, wenn das Objekt komplexer ist.Serialisieren/Deserialisieren Wörterbuch von Objekten mit JSON.NET

Ich habe diese Klasse:

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

In meinem Wörterbuch füge ich ein List<UrlStatus> mit einem Schlüssel von "Redirect Kette" und ein paar einfachen Strings mit den Tasten "Status", "URL", "Parent URL" . Der String Ich bin zurück aus JSON.Net immer sieht wie folgt aus:

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

Der Code Ich verwende sieht serialisiert wie:

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

deserialisieren ich tue:

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

Das Dictionary kommt wieder gut, alle Strings kommen wieder gut, aber die Liste wird nicht richtig deserialisiert. Er kommt gerade zurück, als

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

Natürlich habe ich wieder diese Zeichenfolge deserailize kann und ich das richtige Objekt, aber es scheint wie JSON.Net dies für mich getan haben sollte. Natürlich mache ich etwas falsch, aber ich weiß nicht, was es ist.

Antwort

43

Ich denke, das ist ein Fehler in einer älteren Version von Json.NET. Wenn Sie nicht bereits die neueste Version verwenden, aktualisieren Sie sie und versuchen Sie es erneut.

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

Bearbeiten, ich habe gerade bemerkt, dass Sie eine Liste erwähnt. TypeNameHandling sollte auf Alle festgelegt werden.

Dokumentation: TypeNameHandling setting

+1

Ich Json.NET 3.5 Release 8. Verwendung ich auch die Zip erneut heruntergeladen sicher zu sein. –

+0

Habe gerade den neuesten Build 53965 ausprobiert, funktionierte immer noch nicht. –

+6

TypeNameHandling = TypeNameHandling.All war der Trick. –

Verwandte Themen