【问题标题】:Json Deserialize Object crashingJson反序列化对象崩溃
【发布时间】:2016-10-06 07:38:09
【问题描述】:

我正在尝试将此 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"
                    },
            }
}

这是我用来反序列化它的代码:

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

但是我可以让 Hotkey 对象与 Json Deserialize 一起使用。我已经尝试了很多东西,这是我尝试的最后一个代码:

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”行中崩溃,说格式无效,所以我猜我的类结构中可能遗漏了一些东西。

【问题讨论】:

  • 您的代码无法编译。什么是热键配置?只是通过阅读您的代码,有什么问题吗?为什么只有一个 JSON 文件,却要多次调用反序列化对象?一次反序列化调用应该能够为您获取整个对象图。
  • 这只是Json.Parse(),它被称为“多次”,因为“玩家1”,“玩家2”等键都是动态的,所以不一定会获取这些名称,它可能是任何名称,并且字典反序列化是我发现获取该名称(工作)的方式,但是当我尝试反序列化值时它会崩溃
  • 你能给我们一个可以编译和运行的repro吗?
  • 您似乎缺少ActionSetting 类上的action 属性。

标签: c# .net json json.net


【解决方案1】:

首先,您的 Json 文件中有错误。您没有关闭“玩家 2”的“chatOff”数组。在下面检查它,我在最后一行之前将其关闭:

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

其次,您映射到 Hotkey 的方法很好,但您不能将数组项直接映射到 Hotkey 类。作为替代方案,您可以映射一个新对象来表示您的播放器,然后将属性“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());
}

【讨论】:

  • 仅供参考,但您不需要所有这些JsonProperty 属性。只要名称不区分大小写匹配,JSON.NET 就会将 JSON 中的 camelCase 名称映射到 .NET 类中的 PascalCase 名称。唯一需要JsonProperty 的情况是名称不匹配。否则他们只会制造“噪音”。
  • 当然,@CraigW。我这样做主要是为了简化事情,以防卡特尔想要更改属性名称。
【解决方案2】:

检查您的 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"
        }]
    }
}
}

这是一个 Json 验证器,您可以在其中对其进行测试 JsonValidator 我希望这能解决您的问题。

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2016-12-30
    • 1970-01-01
    相关资源
    最近更新 更多