2017-01-06 17 views
6

私はJSONで非常に新しいです、助けてください!List <KeyValuePair <string、string >>をJSONとしてシリアライズ

私はList<KeyValuePair<string, string>>現在

JSON

ようにシリアライズしようとしています:

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

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

私はthisthisからいくつかの例に言及しました。

これは私のKeyValuePairJsonConverterです:JsonConverter

public class KeyValuePairJsonConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     List<KeyValuePair<object, object>> list = value as List<KeyValuePair<object, object>>; 
     writer.WriteStartArray(); 
     foreach (var item in list) 
     { 
      writer.WriteStartObject(); 
      writer.WritePropertyName(item.Key.ToString()); 
      writer.WriteValue(item.Value.ToString()); 
      writer.WriteEndObject(); 
     } 
     writer.WriteEndArray(); 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(List<KeyValuePair<object, object>>); 
    } 

    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"].ToString(); 
     } 

     if (FieldExists("Value", jsonObject)) 
     { 
      return jsonObject["Value"].ToString(); 
     } 
     return null; 
    } 

    private bool FieldExists(string fieldName, JObject jsonObject) 
    { 
     return jsonObject[fieldName] != null; 
    } 
} 

私はあなたがNewtonsoftと辞書を使用することができ、この

List<KeyValuePair<string, string>> valuesList = new List<KeyValuePair<string, string>>(); 
Dictionary<string, string> valuesDict = SomeDictionaryMethod(); 

foreach(KeyValuePair<string, string> keyValue in valuesDict) 
{ 
    valuesList.Add(keyValue); 
} 

JsonSerializerSettings jsonSettings = new JsonSerializerSettings { Converters = new [] {new KeyValuePairJsonConverter()} }; 
string valuesJson = JsonConvert.SerializeObject(valuesList, jsonSettings); 
+1

'objectType == typeof(List >); 'を'objectType == typeof(List >);に変更してくださいCanConvertメソッド –

+4

1つの質問 - なぜDictionaryの代わりにKeyValuePairsのリストを使用していますか? –

+1

@SergeyBerezovskiyあなたは正しいです!私は何を使うべきかを捜しながら失われてしまったと思って、複雑なことを終わらせました。ありがとうございました! – maryhadalittlelamb

答えて

10

のようなWebサービスメソッドからそれを呼び出しています:

var dict = new Dictionary<int, string>(); 
    dict.Add(1, "one"); 
    dict.Add(2, "two"); 

    var output = Newtonsoft.Json.JsonConvert.SerializeObject(dict); 

出力:

詳細については、 @Sergey Berezovskiyから
{"1":"one","2":"two"} 

編集

感謝。

現在、Newtonsoftを使用していますので、List<KeyValuePair<object, object>>Dictionary<object,object>に変更し、パッケージのserializeおよびdeserializeメソッドを使用してください。

+1

彼はすでにNewtonsoft –

+0

を使用していますので、List >をDictionnary に変更するだけです。私は自分のアンカーを編集する – OrcusZ

+1

それは私がコメントで彼に尋ねたものです。 KeyValuePairsのリストを辞書に変更することは必ずしも可能ではありません。例 - KVPを使用して、Tupleまたはクラスを作成する代わりにKey-Valueを渡すことができます。また、同じKeyで多くのKey-Valueペアを持つことができます。辞書では当てはまりません。 –

0

私はネイティブなC#を使って同様の問題を解決したいとは思っていませんでした。これは.net 4、jquery 3.2.1、backbone 1.2.0を使っていました。

私の問題は、List<KeyValuePair<...>>がコントローラからバックボーンモデルに処理されることでしたが、そのモデルを保存したときにコントローラはリストをバインドできませんでした。

public class SomeModel { 
    List<KeyValuePair<int, String>> SomeList { get; set; } 
} 

[HttpGet] 
SomeControllerMethod() { 
    SomeModel someModel = new SomeModel(); 
    someModel.SomeList = GetListSortedAlphabetically(); 
    return this.Json(someModel, JsonBehavior.AllowGet); 
} 

ネットワークキャプチャ:このセットが適切に裏でそれを変更することなくモデルを保存しようとしているmodel.jsが結合SomeModelオブジェクトが同じを持っている原因となるSomeList

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

しかし、にもかかわらず、リクエストボディ内のパラメータが、すべてのキーと値として長さがnullだった:

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

私は見つけることができる唯一のものは、KeyValuePairはsomethinの構造ではないということですこれは、このようにインスタンス化することができます。私がやってしまったことは以下の通りです:

  • キー、値フィールドが含まどこかのモデルラッパー追加:カスタムラッパーオブジェクトを受け入れるようにあなたのバインディング・クラスのモデルを設定し

    public class KeyValuePairWrapper { 
        public int Key { get; set; } 
        public String 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, String value) 
        { 
         Key = key; 
         Value = value; 
        } 
    } 
    
  • を。

    public class SomeModel 
    { 
        public List<KeyValuePairWrapper> KeyValuePairList{ get; set }; 
    } 
    
  • 多分model.save(NULL、...)が呼び出され、

    [HttpGet] 
    SomeControllerMethod() { 
        SomeModel someModel = new SomeModel(); 
        someModel.KeyValuePairList = GetListSortedAlphabetically(); 
        return this.Json(someModel, JsonBehavior.AllowGet); 
    } 
    
  • 、後で何かをするコントローラのうち、いくつかのJSONデータを取得

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