2009-02-27 13 views
22

ich das folgende Stück von JSON habe:Deserialisierung Problem mit DataContractJsonSerializer

[{ 
    "name": "numToRetrieve", 
    "value": "3", 
    "label": "Number of items to retrieve:", 
    "items": { 
     "1": "1", 
     "3": "3", 
     "5": "5" 
    }, 
    "rules": { 
     "range": "1-2" 
    } 
}, 
{ 
    "name": "showFoo", 
    "value": "on", 
    "label": "Show foo?" 
}, 
{ 
    "name": "title", 
    "value": "Foo", 
    "label": "Foo:" 
}] 

All in one line-Version (geeignet für eine Stringliteral):

[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}] 

In dem obigen Beispiel name , value und label sind erforderlich, aber items und rules sind optional.

Hier ist die Klasse Ich versuche, in deserialisieren:

using System.Collections; 
using System.Collections.Generic; 
using System.Runtime.Serialization; 

namespace foofoo 
{ 
    [DataContract] 
    public sealed class FooDef 
    { 
     [DataMember(Name = "name", IsRequired = true)] 
     public string Name { get; set; } 

     [DataMember(Name = "value", IsRequired = true)] 
     public string Value { get; set; } 

     [DataMember(Name = "label", IsRequired = true)] 
     public string Label { get; set; } 

     [DataMember(Name = "items", IsRequired = false)] 
     public Dictionary<string, string> Items { get; set; } 

     [DataMember(Name = "rules", IsRequired = false)] 
     public Dictionary<string, string> Rules { get; set; } 
    } 
} 

Hier ist der Code, den ich deserialisiert verwenden:

var json = new DataContractJsonSerializer(typeof(List<FooDef>)); 
var bar = "[{\"name\":\"numToRetrieve\",\"value\":\"3\",\"label\":\"Number of items to retrieve:\",\"items\":{\"1\":\"1\",\"3\":\"3\",\"5\":\"5\"},\"rules\":{\"range\":\"1-2\"}},{\"name\":\"showFoo\",\"value\":\"on\",\"label\":\"Show foo?\"},{\"name\":\"title\",\"value\":\"Foo\",\"label\":\"Foo:\"}]"; 
var stream = new MemoryStream(Encoding.UTF8.GetBytes(bar)); 
var foo = json.ReadObject(stream); 
stream.Close(); 

Alles außer dass einigermaßen gut items und rules leer sind für das geht zuerst FooDef übergeben. Ich habe alles unter der Sonne versucht, um sie zu bevölkern: benutzerdefinierte Klassen, NameValueCollection, KeyValuePair<string, string>, List der beiden letzteren, und jede andere Sammlung, die schien zu gelten. [EDIT: Ich habe vergessen, Hashtable zu versuchen, die wie ein offensichtlicher Kandidat schien. Hat nicht funktioniert.]

Das Problem, wie ich es sehe, ist, dass das Schlüsselstück unter items und rules offen ist. Das heißt, es wird nicht immer range oder 3 genannt werden. Irgendwelche Ratschläge oder Ideen?

Antwort

21

IMHO gibt es keine Möglichkeit zum Deserialisieren der JSON-Zeichenfolge, die Sie in einer .NET-Klasse mit DataContractJsonSerializer bereitgestellt haben.

Das Problem kommt von der Art und Weise DataContractJsonSerializer serialisiert Wörterbücher. Sie könnten einen alternativen Serializer wie Json.NET (den ich sehr empfehlen kann) oder JavaScriptSerializer (ich denke, es war veraltet zugunsten von DataContractJsonSerializer, aber es wird für Ihr Szenario funktionieren).

Sie können auch theserants lesen.

Dokumentation: Serializing Collections - Json.NET

+0

Das ist eine Art, was ich befürchtet habe. Ich habe es vermieden, zu JavaScriptSerializer wegen der Vernachlässigung zu wechseln, aber ich bin froh zu hören, dass es in 3.5 SP1 nicht verwendet wurde. Ich werde es mit dieser Klasse versuchen. – bbrown

+1

Ich habe es mit JavaScriptSerializer versucht und es hat perfekt funktioniert. Ich benutzte Dictionary , aber Hashtable funktionierte auch. – bbrown

+2

+1 für Json.NET –

Verwandte Themen