使用枚举类型进行JSON反序列化

4
我正在尝试使用UnityEngine.JsonUtility从文件中反序列化我的JSON项。它可以正常工作,但是我的枚举类型未被正确转换。我尝试使用EnumMember属性,但仍然没有成功。
如何解决? 注意: 我正在使用此解决方案来读取多个文件并将它们存储在数组中。
[Serializable]
public class EquipementItem
{
    public enum ItemTypes
    {
        None,
        Armor,
        Weapon
    }

    public enum SlotTypes
    {
        Head,
        Shoulders,
        Chest,
        Bracers,
        Gloves,
        Waist,
        Legs,
        Boots,
        Weapon
    }

    public int ID;
    public string Name;

    public ItemTypes ItemType;
    public SlotTypes SlotType;
}

还有 JSON 文件

{
"Items": [
{
  "ID": "1",
  "Name": "Basic Sword",
  "ItemType": "Weapon",
  "SlotType": "Weapon"
},
{
  "ID": "2",
  "Name": "Advanced Sword",
  "ItemType": "Weapon",
  "SlotType": "Weapon"
},
{
  "ID": "3",
  "Name": "Leather Chest",
  "ItemType": "Armor",
  "SlotType": "Chest"
}
]}

这是我加载JSON文件的类:

public class Items : MonoBehaviour
{
    public static EquipementItem[] EquipableItems;

    private void Awake()
    {
        string jsonFile = File.ReadAllText(Application.dataPath + "/Scripts/Databases/EquipableItemsDB.json");
        EquipableItems = JsonHelper.FromJson<EquipementItem>(jsonFile);
    }
}

枚举在底层是整数。你尝试将 JSON 中的 "ItemType" 设置为 1,"SlotType" 设置为 2 吗? - ColinM
输入JSON和模型已经在那里了,但是我看不到你的代码 - L.B
你能把这个作为答案发布吗?它有效了! - mashinkata
@L.B 还有什么需要的吗?我注意到我正在使用链接答案中显示的解决方案,我正在通过与那里相同的方式读取json JsonHelper.FromJson<EquipementItem>(jsonString); 那几乎是整个项目,因为这只是一个测试。 - mashinkata
@mashinkata 当我测试一个问题的代码时,我只想要一个可以复制和粘贴的准备好的代码.... 请参阅如何创建最小、完整和可验证的示例 - L.B
@L.B 我已经更新了问题,现在你可以看到我加载 JSON 的地方,但你仍然需要创建一个对象来保存它。 - mashinkata
1个回答

11

你的JSON属性都是字符串,因此它们只能反序列化为String,而Enum值实际上是整数。

如果您将JSON更改为以下内容,则应该可以正常反序列化:

{
    "Items": [
    {
      "ID": "1",
      "Name": "Basic Sword",
      "ItemType": 2,
      "SlotType": 8
    },
    {
      "ID": "2",
      "Name": "Advanced Sword",
      "ItemType": 2,
      "SlotType": 8
    },
    {
      "ID": "3",
      "Name": "Leather Chest",
      "ItemType": 1,
      "SlotType": 2
    }
]}

更新

在撰写本文时,我忘记了存在StringEnumConverter。如果您想在JSON模型中保留可读名称,可以使用它。

[Serializable]
public class EquipementItem
{
    public enum ItemTypes
    {
        None,
        Armor,
        Weapon
    }

    public enum SlotTypes
    {
        Head,
        Shoulders,
        Chest,
        Bracers,
        Gloves,
        Waist,
        Legs,
        Boots,
        Weapon
    }

    public int ID { get; set; }

    public string Name { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    public ItemTypes ItemType { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    public SlotTypes SlotType { get; set; }
}

你能提供一个例子,说明如何使用 Enum.Parse 来完成同样的事情吗? - mashinkata
我已经更新了我的答案,如果你正在使用Newtonsoft.Json,有一种更简单的方法来反序列化枚举。 - ColinM
新顿软件(Newtonsoft.Json)能与Unity的JasonUtility很好地结合吗? - mashinkata
抱歉,我没有注意到提到 UnityEngine.JsonUtility,我已经更新了答案 - 为了代码的简洁性,最好使用整数,因为我猜测你将在代码中进行序列化并输出整数,然后在代码中进行反序列化,而不是手动编辑文件。 - ColinM
但是我想在我的json文件中使用可读的字符串值。我可以覆盖枚举反序列化逻辑,将字符串值转换为我的枚举,这样我就可以做到这一点: "ItemType": "Armor", "SlotType": "Chest" - Konstantin Abakumov
1
@KonstantinAbakumov 使用[JsonConverter(typeof(StringEnumConverter))]修饰你的枚举成员。我已经更新了我的答案以反映这一点。 - ColinM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接