J'ai le morceau suivant de Json:
[{
"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:"
}]
Tout en une ligne d'une ligne (adapté à un littéral à chaîne):
[{\"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:\"}]
Dans l'exemple ci-dessus, name
, value
, et label
sont requis mais items
et rules
sont facultatifs.
Voici la classe que j'essaie de désérialiser dans:
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; }
}
}
Voici le code que j'utilise pour désérialiser:
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();
Tout se passe assez bien, sauf que items
et rules
sont vides pour le premier FooDef
Pass. J'ai tout essayé sous le soleil pour essayer de les faire remplir: classes personnalisées, NameValueCollection
, KeyValuePair<string, string>
, List
de ces derniers et toutes les autres collectes qui semblaient appliquer. [EDIT: J'ai oublié d'essayer Hashtable
, qui semblait être un candidat évident. N'a pas fonctionné.]
Comme je le vois, le problème est que la pièce clé sous items
et rules
est ouverte. C'est-à-dire que cela ne va pas toujours être appelé range
ou 3
. Des conseils ou des idées?
IMHO Il n'y a aucun moyen de désérialiser la chaîne JSON que vous avez fournie dans une classe .NET en utilisant DatacontractjsonSerializer.
Le problème vient de la manière DatacontractjsonSerializer sérialiser les dictionnaires. Vous pouvez utiliser un sérialisateur alternatif tel que JSON.NET (que je recommande vivement) ou Javascriptsérialiseur (Je pense que cela a été obsolète en faveur de DataContractJsonSonerializer, mais cela fonctionnera pour votre scénario ).
Vous pouvez également lire celles-cirants .
Documentation: Collections Serializing - JSON.net
http://social.msdn.microsoft.com/forums/en-us/wcf/thread/071f73bb-e141-4a68-ae61-05635382934f
Vérifiez cet article - il a résolu mon problème presque parfaitement. Je devais changer de type objet [] à une chaîne, mais je n'utilise que des chaînes: touches de type chaîne/paires de valeur, donc pas de problèmes là-bas.