web-dev-qa-db-fra.com

Sérialisation JSON C # du dictionnaire en {clé: valeur, ...} au lieu de {clé: clé, valeur: valeur, ...}

Est-il possible de sérialiser un dictionnaire .Net <Key, Value> en JSON avec DataContractJsonSerializer au format suivant:

{
  key0:value0,
  key1:value1,
  ...
}

J'utilise Dictionnaire <K, V>, car il n'y a pas de structure prédéfinie des entrées.

Je suis intéressant juste pour DataContractJsonSerializer résultat! J'ai déjà trouvé un exemple "Surrogate", mais il y a une "donnée" supplémentaire dans la sortie, et si le dictionnaire <K, String> l'est, l'échappement est également faux.


J'ai trouvé la solution, quel besoin! Tout d’abord, une classe "dictionnaire" sérialisable: (Bien sûr, cet exemple ne fonctionne que dans un sens, mais je n’ai pas besoin de désérialisation)

[Serializable]
public class MyJsonDictionary<K, V> : ISerializable {
    Dictionary<K, V> dict = new Dictionary<K, V>();

    public MyJsonDictionary() { }

    protected MyJsonDictionary( SerializationInfo info, StreamingContext context ) {
        throw new NotImplementedException();
    }

    public void GetObjectData( SerializationInfo info, StreamingContext context ) {
        foreach( K key in dict.Keys ) {
            info.AddValue( key.ToString(), dict[ key ] );
        }
    }

    public void Add( K key, V value ) {
        dict.Add( key, value );
    }

    public V this[ K index ] {
        set { dict[ index ] = value; }
        get { return dict[ index ]; }
    }
}

Usage:

public class MainClass {
    public static String Serialize( Object data ) {
        var serializer = new DataContractJsonSerializer( data.GetType() );
        var ms = new MemoryStream();
        serializer.WriteObject( ms, data );

        return Encoding.UTF8.GetString( ms.ToArray() );
    }

    public static void Main() {
        MyJsonDictionary<String, Object> result = new MyJsonDictionary<String, Object>();
        result["foo"] = "bar";
        result["Name"] = "John Doe";
        result["Age"] = 32;
        MyJsonDictionary<String, Object> address = new MyJsonDictionary<String, Object>();
        result["Address"] = address;
        address["Street"] = "30 Rockefeller Plaza";
        address["City"] = "New York City";
        address["State"] = "NY";

        Console.WriteLine( Serialize( result ) );

        Console.ReadLine();
    }
}

Et le résultat:

{
      "foo":"bar",
      "Name":"John Doe",
      "Age":32,
      "Address":{
         "__type":"MyJsonDictionaryOfstringanyType:#Json_Dictionary_Test",
         "Street":"30 Rockefeller Plaza",
         "City":"New York City",
         "State":"NY"
      }
   }
59
Aaaaaaaa

Json.NET fait ça ...

Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("key1", "value1");
values.Add("key2", "value2");

string json = JsonConvert.SerializeObject(values);
// {
//   "key1": "value1",
//   "key2": "value2"
// }

Autres exemples: Sérialisation de collections avec Json.NET

54
James Newton-King

utilisez la propriété UseSimpleDictionaryFormat sur DataContractJsonSerializer et définissez-la sur true.

Fait le travail :)

13
Maziar Taheri

J'utilise MVC4 avec ce code (notez les deux paramètres à l'intérieur de ToDictionary)

 var result = new JsonResult()
 {
     Data = new
     {
         partials = GetPartials(data.Partials).ToDictionary(x => x.Key, y=> y.Value)
     }
 };

Je reçois ce qui est attendu:

{"partials":{"cartSummary":"\u003cb\u003eCART SUMMARY\u003c/b\u003e"}}

Important: WebAPI dans MVC4 utilise immédiatement la sérialisation JSON.NET, mais pas le résultat d'action Web JsonResult standard. Par conséquent, je recommande d'utiliser un ActionResult personnalisé pour forcer la sérialisation JSON.NET. Vous pouvez également obtenir un formatage agréable

Voici un résultat d’action simple JsonNetResult

http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx

Vous verrez la différence (et pourrez vous assurer que vous utilisez le bon) lors de la sérialisation d'une date:

Façon Microsoft:

 {"wireTime":"\/Date(1355627201572)\/"}

Manière JSON.NET:

 {"wireTime":"2012-12-15T19:07:03.5247384-08:00"}
4
Simon_Weaver

Malheureusement, cela n’est actuellement pas possible dans la dernière version de DataContractJsonSerializer. Voir: http://connect.Microsoft.com/VisualStudio/feedback/details/558686/datacontractjsonserializer-should-serialize-dictionary-k-v-as-a-json-associative-array

La solution de contournement actuellement suggérée consiste à utiliser JavaScriptSerializer en tant que marque suggérée ci-dessus.

Bonne chance!

2
Justin Fyles

La classe MyJsonDictionary a bien fonctionné pour moi SAUF que la sortie résultante est encodée en XML - donc "0" devient "00". Je suis actuellement bloqué sur .NET 3.5, comme beaucoup d'autres, de nombreuses autres solutions ne sont donc pas disponibles. "Met les images à l'envers" et s'est rendu compte que je ne pourrais jamais convaincre Microsoft de me donner le format que je voulais mais ...

string json = XmlConvert.DecodeName (xmlencodedJson);

TADA!

Le résultat correspond à ce que vous vous attendriez à voir - lisible par l'homme et codé non XML. Fonctionne dans .NET 3.5.

0
Mark Z. Kumler