2016-10-05 5 views
0

このJSONファイルをオブジェクトに逆シリアル化しようとしていますが、動作させることができません。Json Deserializeオブジェクトがクラッシュする

JSON:

"hotkeySets": { 
    "Player 1": { 
      "chatOff": [ 
        { 
        "actionsetting": { 
          "action": "Togglelist" 
         }, 
         "keysequence": "Ctrl+B" 
        }, 
        { 
         "actionsetting": { 
          "action": "Copy" 
         }, 
         "keysequence": "Ctrl+C" 
        }, 
        { 
         "actionsetting": { 
          "useObject": 3308, 
          "useType": "SelectUseTarget" 
         }, 
         "keysequence": "F10" 
        }, 
       ], 
       "chatOn": [ 
        { 
         "actionsetting": { 
          "action": "Select All" 
         }, 
         "keysequence": "Ctrl+A" 
        }, 
        { 
         "actionsetting": { 
          "chatText": "heal friend", 
          "sendAutomatically": true 
         }, 
         "keysequence": "Ctrl+F1" 
        }, 
        { 
         "actionsetting": { 
          "action": "Copy" 
         }, 
         "keysequence": "Ctrl+C" 
        }, 
       ] 
      }, 
      "Player 2": { 
       "chatOff": [ 
        { 
         "actionsetting": { 
          "action": "ToggleBattlelist" 
         }, 
         "keysequence": "Ctrl+B" 
        }, 
        { 
         "actionsetting": { 
          "action": "Copy" 
         }, 
         "keysequence": "Ctrl+C" 
        }, 
      } 
} 

そして、ここでは、私はそれをデシリアライズするために使用しているコードです:

JToken hotkeyConfig = JObject.Parse(json) 
JToken hotkeysSet = hotkeyConfig.SelectToken("hotkeySets"); 

var sets = JsonConvert.DeserializeObject<Dictionary<string, JObject>>(hotkeysSet.ToString()); 

foreach (var hotkeySet in sets) { 
    string hotkeySetName = hotkeySet.Key; // "Player 1" etc.. 
    List<Hotkey> hotkeys = new List<Hotkey>(); 

    foreach (var hotkey in hotkeySet.Value) { 

     Hotkey htk = JsonConvert.DeserializeObject<Hotkey>(hotkey.Value.ToString());  
    } 
} 

しかし、私はホットキーオブジェクトはJSONデシリアライズで動作するように取得することができます。私は多くのことを試してみましたが、ここで私が試した最後のコードは次のとおりです。

public class Hotkey { 

     [JsonProperty("actionsetting")] 
     public ActionSetting actionsetting; 

     [JsonProperty("keysequence")] 
     public string Shortcut { get; set; } 

     public class ActionSetting { 
      public int useObject{ get; set; } 

      public string chatText { get; set; } 

      public string useType{ get; set; } 

      public bool sendAutomatically{ get; set; } 
     } 
    } 

それは無効な形式を言って、ライン「JsonConvert.DeserializeObject」でクラッシュしていますので、おそらく私は私のクラス構造で何かが欠けていますI推測。

+0

あなたのコードがコンパイルされません。 hotkeyConfigとは何ですか? コードを読むだけで何か間違っていますか? JSONファイルを1つしか持たないうちにオブジェクトを何回もデシリアライズするのはなぜですか?デシリアライズを1回呼び出すだけで、オブジェクトグラフ全体を取得できるはずです。 –

+0

これはちょうどJson.Parse()です。 "Player 1"、 "Player 2"などのキーはすべて動的なので、必ずしもそれらの名前を取得するわけではありません。どんな名前でも、辞書はその名前を得るために見つけた方法であったが(作業中)、値を脱直列化しようとするとクラッシュする – Cartel

+0

コンパイルして実行できる再プロンプトを手に入れることはできますか? –

答えて

0

まず、Jsonファイルにエラーがあります。あなたは "chat 2"の "chatOff"配列を閉じていません。私は最後の前の行にそれを閉じたところ、以下のことを確認してください:

"Player 2": { 
    "chatOff": [ 
     { 
      "actionsetting": { 
       "action": "ToggleBattlelist" 
      }, 
      "keysequence": "Ctrl+B" 
     }, 
     { 
      "actionsetting": { 
       "action": "Copy" 
      }, 
      "keysequence": "Ctrl+C" 
     }, 
    ] 
} 

第二に、ホットキーにマップするためにあなたのアプローチは罰金ですが、ホットキークラスに直接お使いの配列項目をマッピングすることはできません。代わりに、新しいオブジェクトをマップしてPlayerを表すことができ、プロパティ "chatOff"と "chatOn"をリストにマップすることができます。あなたのJSONクラスは次のようになります

public class Player 
{ 
    [JsonProperty("chatOff")] 
    public List<Hotkey> ChatOff { get; set; } 

    [JsonProperty("chatOn")] 
    public List<Hotkey> ChatOn { get; set; } 
} 

public class Hotkey 
{ 
    [JsonProperty("actionsetting")] 
    public ActionSetting ActionSetting; 

    [JsonProperty("keysequence")] 
    public string Shortcut { get; set; } 
} 

public class ActionSetting 
{ 
    [JsonProperty("useObject")] 
    public int UseObject { get; set; } 

    [JsonProperty("chatText")] 
    public string ChatText { get; set; } 

    [JsonProperty("useType")] 
    public string UseType { get; set; } 

    [JsonProperty("sendAutomatically")] 
    public bool SendAutomatically { get; set; } 
} 

最後に、あなたのデシリアライズコードを作成し、次のようになります。

var hotkeyConfig = JObject.Parse(json); 

var playersToken = hotkeyConfig.SelectToken("hotkeySets"); 

var playersDictionary = 
    JsonConvert.DeserializeObject<Dictionary<string, JObject>>(
     playersToken.ToString()); 

foreach (var playerEntry in playersDictionary) 
{ 
    var player = JsonConvert.DeserializeObject<Player>(playerEntry.Value.ToString()); 
} 
+1

ちょうどFYIですが、それらのすべての 'JsonProperty'属性は必要ありません。 JSON.NETは、名前が大文字と小文字を区別しない限り、JSONのcamelCase名を.NETクラスのPascalCase名にマップします。 'JsonProperty'が必要なのは、名前が一致しない場合だけです。そうでなければ "ノイズ"を作成します。 –

+0

ありがとう、それは素晴らしい仕事! – Cartel

+0

確かに、@CraigW。カルテルがプロパティ名を変更したい場合に備えて、私は主に事柄を単純化するためにそれを行います。 – Ismael

0

Jsonの文字列を確認してください。フォーマットが悪いのでエラーが表示されます。ここでは、あなたが投稿したJsonの文字列の正しい形式を教えてくれます。ここ

{ 
"hotkeySets": { 
    "Player 1": { 
     "chatOff": [{ 
      "actionsetting": { 
       "action": "Togglelist" 
      }, 
      "keysequence": "Ctrl+B" 
     }, { 
      "actionsetting": { 
       "action": "Copy" 
      }, 
      "keysequence": "Ctrl+C" 
     }, { 
      "actionsetting": { 
       "useObject": 3308, 
       "useType": "SelectUseTarget" 
      }, 
      "keysequence": "F10" 
     }], 
     "chatOn": [{ 
      "actionsetting": { 
       "action": "Select All" 
      }, 
      "keysequence": "Ctrl+A" 
     }, { 
      "actionsetting": { 
       "chatText": "heal friend", 
       "sendAutomatically": true 
      }, 
      "keysequence": "Ctrl+F1" 
     }, { 
      "actionsetting": { 
       "action": "Copy" 
      }, 
      "keysequence": "Ctrl+C" 
     }] 
    }, 
    "Player 2": { 
     "chatOff": [{ 
      "actionsetting": { 
       "action": "ToggleBattlelist" 
      }, 
      "keysequence": "Ctrl+B" 
     }, { 
      "actionsetting": { 
       "action": "Copy" 
      }, 
      "keysequence": "Ctrl+C" 
     }] 
    } 
} 
} 

は、私は、これはあなたの問題を解決を願って、あなたがJsonValidator それをテストすることができますJSONバリデータです。

関連する問題