Cartel Cartel - 1 month ago 27
C# Question

Json Deserialize Object crashing

I'm trying to deserialize this JSON file into an object, but I can't get it working.

The 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"
},
}
}


And here is the code I'm using to deserialize it:

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());
}
}


But I can get the Hotkey object to work with Json Deserialize. I have tried a lot of things and here is the last code I tried:

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; }
}
}


It's crashing in the line "JsonConvert.DeserializeObject", saying invalid format, so probably I'm missing something in my class structure I guess.

Answer

First of all, there is an error in your Json file. You are not closing the "chatOff" array of "Player 2". Check it below, where I closed it on the line before the last one:

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

Second, your approach to map into Hotkey is fine, but you can not map your array items directly into the Hotkey class. As an alternative, you can map a new object to represent your Player, and then map the properties "chatOff" and "chatOn" into lists. Make your Json classes look like this:

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; }
}

Last, make your deserializing code look like this:

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());
}
Comments