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"
}
}
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
utilisez la propriété UseSimpleDictionaryFormat
sur DataContractJsonSerializer
et définissez-la sur true
.
Fait le travail :)
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"}
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!
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.