2012-05-14 4 views
2

J'utilise Newtonsoft.Json avec la version 4.0.8 et j'essaie de l'utiliser avec l'API Web. donc je voulais désérialiser JSON avecDeserialize Dictionary avec JSON.NET

JsonConvert.DeserializeObject<AClass>(jsonString); 

Cela fonctionne jusqu'à ce que j'ajouté un dictionnaire en tant que propriété à cette classe et je voulais désérialiser.

La chaîne JSON est sous forme de

{ 
    "Date":null, 
    "AString":"message", 
    "Attributes":[ 
        {"Key":"key1","Value":"value1"},  
        {"Key":"key2","Value":"value2"} 
       ], 
    "Id":0, 
    "Description":"... 
} 

Lorsque désérialisation exception de type JsonSerializationException avec le message occures: "ne peut désérialiser tableau JSON en type « System.Collections.Generic.Dictionary`2 [Système .String, System.String] '. "

Qu'est-ce que je fais de mal ici?

Update1: Lors de la sérialisation avec JSON.NET je reçois ce qui suit pour le dictionnaire:

Attributes":{"key1":"value1","key2":"value2"} 

Il semble que WebAPI désérialise l'objet d'une autre manière que Json.Net serait. côté serveur-je utiliser la ligne suivante pour désérialisation implicite:

return new HttpResponseMessage<AClass>(object); 

MAJ2: Pour contourner ce problème, je suis maintenant à suivre côté serveur en ligne. Je le convertis avec le côté serveur Json.Net et le transfère comme chaîne encodée en base64. Json.Net peut donc désérialiser son propre format.

Mais ce n'est toujours pas ce que je veux, donc y a-t-il d'autres suggestions?

+1

Qu'est-ce que JSON obtenez-vous si vous sérialisez la classe? – Rawling

+0

Merci pour votre réponse rapide. J'ai mis à jour ma question en conséquence. – dasheddot

+1

Sauf s'il existe une option sur l'API Web ou sur Newtonsoft pour gérer les dictionnaires de la manière "opposée", je suggère simplement d'utiliser la même bibliothèque à chaque extrémité (serialize/deserialize) si cela est possible. – Rawling

Répondre

3

Il devrait fonctionner si vous déclarez Attributes comme List<KeyValuePair<string, string>>

1

De this post, appelant

JsonConvert.SerializeObject(yourObject, new KeyValuePairConverter()); 

obtient votre JSON dans le format que l'API Web crée pour vous.

Ergo, on pourrait supposer que l'appel

JsonConvert.DeserializeObject<AClass>(jsonString, new KeyValuePairConverter()); 

fera l'inverse et de gérer correctement le style de l'API Web.

Je n'ai aucune idée si cette surcharge existe même, cependant; essayer et voir ce qui se passe ...

+0

Je l'ai essayé mais avec le même résultat. La même exception se produit même avec le keyvaluepairconverter appliqué lors de la désérialisation. – dasheddot

+0

Eh, c'est juste. Ça vaut le coup d'essayer. – Rawling

0

Si c'est.NET 4, vous pouvez utiliser DataContract attributs et le DataContractJsonSerializer Class pour faire respecter le format du message:

[DataContract] 
    public class Message 
    { 
     [DataMember] 
     public DateTime? Date { get; set; } 
     [DataMember] 
     public string AString { get; set; } 
     [DataMember] 
     public Dictionary<string, string> Attributes { get; set; } 
     [DataMember] 
     public int Id { get; set; } 
     [DataMember] 
     public string Description { get; set; } 
    } 

     DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Message)); 

     Message message = null; 
     using (MemoryStream jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString))) 
     { 
      // Deserialize 
      message = (Message)jsonSerializer.ReadObject(jsonStream); 

      // Go to the beginning and discard the current stream contents. 
      jsonStream.Seek(0, SeekOrigin.Begin); 
      jsonStream.SetLength(0); 

      // Serialize 
      jsonSerializer.WriteObject(jsonStream, message); 
      jsonString = Encoding.UTF8.GetString(jsonStream.ToArray()); 
     } 

sérialisation ce Reculez produit le JSON suivant:

{"AString":"message","Attributes":[{"Key":"key1","Value":"value1"},{"Key":"key2","Value":"value2"}],"Date":null,"Description":"...","Id":0} 
+2

Merci, mais je veux le faire avec Json.Net puisque nous l'utilisons déjà à plusieurs endroits dans la solution, donc je ne veux plus vraiment utiliser .Nets DataContractSerializer. – dasheddot

1
Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(strJsonResult);