Liste de sérialisation <KeyValuePair > en tant que JSON

Je suis très nouveau avec JSON, aidez s’il vous plaît!

J’essaie de sérialiser une List<KeyValuePair> tant que JSON

Actuellement:

 [{"Key":"MyKey 1","Value":"MyValue 1"},{"Key":"MyKey 2","Value":"MyValue 2"}] 

Attendu:

 [{"MyKey 1":"MyValue 1"},{"MyKey 2":"MyValue 2"}] 

J’ai cité des exemples de ceci et de ceci .

Ceci est mon KeyValuePairJsonConverter: JsonConverter

 public class KeyValuePairJsonConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { List<KeyValuePair> list = value as List<KeyValuePair>; writer.WriteStartArray(); foreach (var item in list) { writer.WriteStartObject(); writer.WritePropertyName(item.Key.ToSsortingng()); writer.WriteValue(item.Value.ToSsortingng()); writer.WriteEndObject(); } writer.WriteEndArray(); } public override bool CanConvert(Type objectType) { return objectType == typeof(List<KeyValuePair>); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonObject = JObject.Load(reader); var target = Create(objectType, jsonObject); serializer.Populate(jsonObject.CreateReader(), target); return target; } private object Create(Type objectType, JObject jsonObject) { if (FieldExists("Key", jsonObject)) { return jsonObject["Key"].ToSsortingng(); } if (FieldExists("Value", jsonObject)) { return jsonObject["Value"].ToSsortingng(); } return null; } private bool FieldExists(ssortingng fieldName, JObject jsonObject) { return jsonObject[fieldName] != null; } } 

Je l’appelle depuis une méthode WebService comme celle-ci

 List<KeyValuePair> valuesList = new List<KeyValuePair>(); Dictionary valuesDict = SomeDictionaryMethod(); foreach(KeyValuePair keyValue in valuesDict) { valuesList.Add(keyValue); } JsonSerializerSettings jsonSettings = new JsonSerializerSettings { Converters = new [] {new KeyValuePairJsonConverter()} }; ssortingng valuesJson = JsonConvert.SerializeObject(valuesList, jsonSettings); 

Vous pouvez utiliser Newtonsoft et dictionnaire:

  var dict = new Dictionary(); dict.Add(1, "one"); dict.Add(2, "two"); var output = Newtonsoft.Json.JsonConvert.SerializeObject(dict); 

La sortie est:

 {"1":"one","2":"two"} 

modifier

Merci à @Sergey Berezovskiy pour l’information.

Vous utilisez actuellement Newtonsoft, il vous suffit donc de modifier votre object List> en Dictionary et d’utiliser la méthode sérialiser et désérialiser du package.

Donc, je ne voulais pas utiliser autre chose que le C # natif pour résoudre un problème similaire. Par exemple, il utilisait .net 4, jquery 3.2.1 et Backbone 1.2.0.

Mon problème était que List> serait traité hors du contrôleur dans un modèle de List> principal, mais lorsque j’ai enregistré ce modèle, le contrôleur n’a pas pu lier List.

 public class SomeModel { List> SomeList { get; set; } } [HttpGet] SomeControllerMethod() { SomeModel someModel = new SomeModel(); someModel.SomeList = GetListSortedAlphabetically(); return this.Json(someModel, JsonBehavior.AllowGet); } 

capture du réseau:

 "SomeList":[{"Key":13,"Value":"aaab"},{"Key":248,"Value":"aaac"}] 

Toutefois, même si définir correctement SomeList dans le fichier backing model.js, si vous tentez de sauvegarder le modèle sans aucune modification, l’object de liaison SomeModel a la même longueur que les parameters du corps de la requête, mais toutes les clés et valeurs sont nulles:

 [HttpPut] SomeControllerMethod([FromBody] SomeModel){ SomeModel.SomeList; // Count = 2, all keys and values null. } 

La seule chose que j’ai pu trouver est que KeyValuePair est une structure et non quelque chose qui peut être instancié de cette manière. Ce que j’ai fini par faire est le suivant:

  • Ajoutez un wrapper de modèle quelque part contenant des champs de clé et de valeur:

     public class KeyValuePairWrapper { public int Key { get; set; } public Ssortingng Value { get; set; } //default constructor will be required for binding, the Web.MVC binder will invoke this and set the Key and Value accordingly. public KeyValuePairWrapper() { } //a convenience method which allows you to set the values while sorting public KeyValuePairWrapper(int key, Ssortingng value) { Key = key; Value = value; } } 
  • Configurez votre modèle de classe de liaison pour accepter votre object wrapper personnalisé.

     public class SomeModel { public List KeyValuePairList{ get; set }; } 
  • Obtenir des données JSON d’un contrôleur

     [HttpGet] SomeControllerMethod() { SomeModel someModel = new SomeModel(); someModel.KeyValuePairList = GetListSortedAlphabetically(); return this.Json(someModel, JsonBehavior.AllowGet); } 
  • Faites quelque chose plus tard, peut-être que model.save (null, …) est appelé

     [HttpPut] SomeControllerMethod([FromBody] SomeModel){ SomeModel.KeyValuePairList ; // Count = 2, all keys and values are correct. }