【问题标题】:How to use JsonConstructor Attribute in System.Text.Json如何在 System.Text.Json 中使用 JsonConstructor 属性
【发布时间】:2021-12-28 05:41:29
【问题描述】:

我使用的是 .NET 提供的 Json 命名空间,而不是 Newtonsoft 的命名空间。我有一段代码:

            string text;
            text = File.ReadAllText(EntityDirectory + @"\Json\AbilityTemplates.json");
            foreach (AbilityTemplate template in JsonSerializer.Deserialize<List<AbilityTemplate>>(text)) {
                loaderInterface.AddAbilityTemplate(template);
            }

当代码运行到 JsonSerializer.Deserialize 时,抛出了一个 execption。

System.Text.Json.JsonException: 'JSON 值无法转换为 System.Collections.Generic.List`1[Enigma.Game.AbilityTemplate]。路径:$ |行号:0 | BytePositionInLine: 1.'

这是我拥有的 Json 文本:

{
  {
    "ID": "StandardShot",
    "Price": "10",
    "Size": "1",
    "Rarity": "Common",
    "AbilityEffectFactory": "StandardShotEffectFactory"
  },
  {
    "ID": "SelfDestructSingleDamage",
    "Price": "0",
    "Size": "0",
    "Rarity": "NotForPlayer",
    "AbilityEffectFactory": "SelfDestructSingleDamageEffectFactory"
  }
}

我用JsonConstructor Attribute写了一个构造函数,但是好像不行:

        public AbilityTemplate(string id, int price, int size, Rarity rarity, AbilityEffectFactory abilityEffectFactory) {
            Id = id;
            Price = price;
            Size = size;
            Rarity = rarity;
            AbilityEffectFactory = abilityEffectFactory;
        }

        [JsonConstructor]
        public AbilityTemplate(string id, int price, int size, Rarity rarity, string abilityEffectFactory) : this(id, price, size, rarity, AbilityEffectFactory.Dictionary[abilityEffectFactory]) { }

Rarity 是一种枚举类型。

—————————编辑—————————

我把括号从{}改成[],也让json文本中的字段和参数名完全匹配,但是还是不行。 这是我的新 Json 文本:

[
  {
    "id": "StandardShot",
    "price": "10",
    "size": "1",
    "rarity": "Common",
    "abilityEffectFactory": "StandardShotEffectFactory"
  },
  {
    "id": "SelfDestructSingleDamage",
    "price": "0",
    "size": "0",
    "rarity": "NotForPlayer",
    "abilityEffectFactory": "SelfDestructSingleDamageEffectFactory"
  }
]

System.InvalidOperationException: 'Enigma.Game.AbilityTemplate' 类型的反序列化构造函数中的每个参数都必须绑定到反序列化时的对象属性或字段。每个参数名称必须与对象上的属性或字段匹配。匹配可以不区分大小写。'

【问题讨论】:

标签: c# json .net system.text.json


【解决方案1】:

第一个问题在于您的 JSON 值。您应该使用 [ ] 而不是 { } 在 JSON 文件中开始和结束数组。要检查 JSON 文件的有效性,您可以使用在线工具,例如 https://codebeautify.org/jsonviewer。这个网站非常适合验证和编辑 JSON 文件。

更改 JSON 文件后,您可以非常轻松地对其进行反序列化。首先,您应该创建一个与 JSON 文件具有相同属性的模型。请注意,属性类型应与 JSON 文件中的类型匹配。示例 JSON 文件中的所有键都是字符串。

对于这个示例文件,您应该制作如下模型:

public class weatherForecastModel
    {
        public string ID { get; set; }
        public string Price { get; set; }
        public string Size { get; set; }
        public string Rarity { get; set; }
        public string AbilityEffectFactory { get; set; }
    }

之后,您可以使用一行代码将 JSON 反序列化为您的模型:

var jsonString = File.ReadAllText(EntityDirectory + @"\Json\AbilityTemplates.json");
var weatherForecast = JsonSerializer.Deserialize<List<weatherForecastModel>>(jsonString);

或者,如果你使用 Newtonsoft,你可以使用:

var res = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);

【讨论】:

  • 但我想使用 JsonConstructor 来摆脱不必要的附加类。
  • 好吧好吧。但我认为我的解决方案更具可读性和简单性。我总是通过关注 KISS 原则,通过简单的解决方案来解决问题 :) en.wikipedia.org/wiki/KISS_principle
猜你喜欢
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2020-07-13
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
相关资源
最近更新 更多