如何在 System.Text.Json 中使用 JsonConstructor 属性

     2023-02-15     152

关键词:

【中文标题】如何在 System.Text.Json 中使用 JsonConstructor 属性【英文标题】:How to use JsonConstructor Attribute in System.Text.Json 【发布时间】: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' 类型的反序列化构造函数中的每个参数都必须绑定到反序列化时的对象属性或字段。每个参数名称必须与对象上的属性或字段匹配。匹配可以不区分大小写。'

【问题讨论】:

将第一对 ' ' 替换为 "[ ]" 表示你有一个 List/Array 我想你已经完成了。只需删除带有JsonConstructor 属性标记的构造函数,就可以开始了。 能否请您edit 分享minimal reproducible example 的问题?请注意 System.Text.Json 默认区分大小写;如果您的属性名称是Id,您可能需要设置JsonSerializerOptions.PropertyNameCaseInsensitive = true,如JsonSerializer.Deserialize fails 所示。您还需要使用JsonStringEnumConverter 将枚举序列化为字符串,请参阅this answer 至ASP.NET MVC Core API Serialize Enums to String。 【参考方案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

如何使用 JsonConverter 在 System.Text.Json.JsonSerializer.Serialize() 中排除属性被序列化

】如何使用JsonConverter在System.Text.Json.JsonSerializer.Serialize()中排除属性被序列化【英文标题】:HowtoexcludeapropertyfrombeingserializedinSystem.Text.Json.JsonSerializer.Serialize()usingaJsonConverter【发布时间】:2020-02-2206:59:16【问题描述】:我希望能... 查看详情

如何使用 System.Text.Json 忽略错误值

】如何使用System.Text.Json忽略错误值【英文标题】:HowtoignorefalsevalueswithSystem.Text.Json【发布时间】:2020-02-0203:15:00【问题描述】:我正在我的.NETCore3.0应用程序中从Newtonsoft.Json迁移到System.Text.Json。我试图忽略错误值。在System.Text.Js... 查看详情

在system.text.json中使用构造函数进行反序列化(代码片段)

在System.Text.Json中使用构造函数进行反序列化有的时候,我们希望一些类型在实例化之后,就无法更改,也就是说,属性只读,但是如果这样,System.Text.Json就无法对属性进行赋值,可以这样:classUserModelpublicstaticstringUsernameget;set;publicstaticstrin... 查看详情

不再可能使用 system.text.json 在 c# 中进行序列化/反序列化

】不再可能使用system.text.json在c#中进行序列化/反序列化【英文标题】:Isusingthesystem.text.jsonnolongerpossibleforserializing/deserialiinginc#【发布时间】:2021-11-2102:15:09【问题描述】:正如2019年9月更新的官方microsoft文档中所述,它表示可... 查看详情

如何使用system.text.json序列化datetimeoffset为unix时间戳

在.NET中,日期和时间通常使用DateTime或DateTimeOffset来表示。这两种数据类型都可以表示日期和时间,但它们之间有一些明显的区别。DateTime是不带时区信息的,而DateTimeOffset是带时区偏移量的,可以用来表示一个特... 查看详情

是否可以在 System.Text.Json 中找到未映射的属性?

】是否可以在System.Text.Json中找到未映射的属性?【英文标题】:IsitpossibletofindunmappedpropertiesinSystem.Text.Json?【发布时间】:2021-08-2319:14:38【问题描述】:是否可以使用System.Text.Json.JsonSerializer找到未映射的属性?我正在访问一个返... 查看详情

在system.text.json中使用构造函数进行反序列化(代码片段)

在System.Text.Json中使用构造函数进行反序列化有的时候,我们希望一些类型在实例化之后,就无法更改,也就是说,属性只读,但是如果这样,System.Text.Json就无法对属性进行赋值,可以这样:classUserModelpublicstaticstringUsernameget;set;publicstaticstrin... 查看详情

在命名空间中找不到 System.Text.Json.JsonReaderException

】在命名空间中找不到System.Text.Json.JsonReaderException【英文标题】:System.Text.Json.JsonReaderExceptionisn\'tfoundinnamespace【发布时间】:2020-09-0900:15:50【问题描述】:我正在将.NETFramework4.5项目转换为.NETCore3.1。我的测试曾经使用Newtonsoft.Jso... 查看详情

(de) 使用 System.Text.Json 序列化流

】(de)使用System.Text.Json序列化流【英文标题】:(de)SerializingstreamusingSystem.Text.Json【发布时间】:2021-09-3007:36:13【问题描述】:我正在尝试使用System.Text.Json的JsonSerializer将对象序列化为MemoryStream。我无法在文档中找到它的实现/方法... 查看详情

如何将类字段与 System.Text.Json.JsonSerializer 一起使用?

】如何将类字段与System.Text.Json.JsonSerializer一起使用?【英文标题】:HowtouseclassfieldswithSystem.Text.Json.JsonSerializer?【发布时间】:2019-09-2718:25:58【问题描述】:我最近将一个解决方案升级为全部.NETCore3,并且我有一个需要类变量为... 查看详情

如何使用 System.Text.Json 处理可为空的引用类型?

】如何使用System.Text.Json处理可为空的引用类型?【英文标题】:HowtodealwithnullablereferencetypeswithSystem.Text.Json?【发布时间】:2020-02-0214:07:58【问题描述】:我已将我的项目升级到netcore3.0,我正在重构一个项目以使用新的可为空引... 查看详情

使用 System.Text.Json 从 json 文件读取到 IEnumerable

】使用System.Text.Json从json文件读取到IEnumerable【英文标题】:ReadfromjsonfileintoIEnumerableusingSystem.Text.Json【发布时间】:2022-01-0318:18:55【问题描述】:使用System.Text.Json在C#中从json读取到IEnumerable时遇到问题...这是错误:System.Text.Json.Js... 查看详情

如何使用 System.Text.Json API 将流反序列化为对象

】如何使用System.Text.JsonAPI将流反序列化为对象【英文标题】:HowtodeserializestreamtoobjectusingSystem.Text.JsonAPIs【发布时间】:2020-02-1902:00:12【问题描述】:我正在以流形式接收来自Webapi调用的响应,需要将其反序列化为模型。这是一... 查看详情

如何强制 System.Text.Json.JsonElement.GetProperty 使用不区分大小写的方法搜索属性?

】如何强制System.Text.Json.JsonElement.GetProperty使用不区分大小写的方法搜索属性?【英文标题】:HowtoforceSystem.Text.Json.JsonElement.GetPropertytosearchforpropertiesusingcase-insensitivemethod?【发布时间】:2022-01-1819:15:39【问题描述】:这是我的JSON... 查看详情

将 false 反序列化为 null (System.Text.Json)

...某种原因,它在应该使用null的地方使用了false。我不知道如何正确反序列化它。我试图创建一个自定义JsonConverter来解决这个问题,但无法这样做。我想避免使用动态类型。我应该如 查看详情

如何使用 System.Text.Json 序列化/反序列化非枚举类型的嵌套字典?

】如何使用System.Text.Json序列化/反序列化非枚举类型的嵌套字典?【英文标题】:HowtoSerialize/deserializeanesteddictionaryofnon-enumtypeswithSystem.Text.Json?【发布时间】:2021-07-2215:31:03【问题描述】:我正在尝试序列化这本字典:IDictionary<... 查看详情

使用 System.Text.Json 获取嵌套属性

】使用System.Text.Json获取嵌套属性【英文标题】:GettingnestedpropertieswithSystem.Text.Json【发布时间】:2020-08-1614:53:34【问题描述】:我在我的项目中使用System.Text.Json,因为我正在处理大型文件,因此我也决定使用它来处理GraphQL响应... 查看详情

JsonConverter 等效于使用 System.Text.Json

】JsonConverter等效于使用System.Text.Json【英文标题】:JsonConverterequivalentinusingSystem.Text.Json【发布时间】:2019-05-2912:15:03【问题描述】:我开始在.netCore3.0应用程序中将我拥有的一些代码从Newtonsoft.Json迁移到System.Text.Json。我从迁移了... 查看详情