C# Json 反序列化动态类型

问题描述 投票:0回答:1

我们有一个 C# 控制台应用程序,可以调用多个第 3 方 API。我们从这些 API 获取 JSON 格式的数据。我们正在尝试将 JSON 反序列化为已定义的类。问题是 json 中的“custom_attributes”属性包含具有以下结构的对象:

{
    ...other properties
    "custom_attributes": [
        {
            "attribute_code": "required_options",
            "value": "simple"
        },
        {
            "attribute_code": "category_ids",
            "value": [
                "2"
            ]
        },
        {
            "attribute_code": "has_options",
            "value": "0"
        }
    ]
}

如您所见,“value”属性可以具有“string”类型或“string[]”类型作为值。

目前,我们有以下代码:

public class MyApiResponseClass 
{
    ... other properties
    [JsonProperty("custom_attributes")]
    public List<CustomAttribute> CustomAttributes { get; set; } = new();
}

public class CustomAttribute
{
    [JsonProperty("attribute_code")]
    public string AttributeCode { get; set; } = string.Empty;

    [JsonProperty("value")]
    public object Value { get; set; } = string.Empty;
}
var response = JsonConvert.DeserializeObject<MyApiResponseClass>(responseContent);

这会产生以下错误:

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“System.Object”,因为该类型需要 JSON 原始值(例如字符串、数字、布尔值、null)才能正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 原始值(例如字符串、数字、布尔值、null),或者将反序列化类型更改为数组或实现集合接口(例如 ICollection、IList)的类型,例如 List,可以从 JSON 数组反序列化。还可以将 JsonArrayAttribute 添加到类型中以强制其从 JSON 数组进行反序列化。 路径“items[0].custom_attributes[17].value”,第 1 行,位置 3119。”

任何帮助将不胜感激!

c# json json.net
1个回答
0
投票

似乎抛出了异常,因为您正在将

Value
属性预先初始化为
string
:

public object Value { get; set; } = string.Empty;

如果我删除初始值,异常就会消失:

public class CustomAttribute
{
    [JsonProperty("attribute_code")]
    public string AttributeCode { get; set; } = string.Empty;

    [JsonProperty("value")]
    public object Value { get; set; } // = string.Empty;
}

演示小提琴#1 这里

大概你不希望这样,但用

ObjectCreationHandling.Replace
标记该属性似乎也可以解决问题:

public class CustomAttribute
{
    [JsonProperty("attribute_code")]
    public string AttributeCode { get; set; } = string.Empty;

    [JsonProperty("value", ObjectCreationHandling = ObjectCreationHandling.Replace)]
    public object Value { get; set; } = string.Empty;
}

由于您已经使用 Newtonsoft 属性注释您的模型,这似乎是破坏性最小的修复。演示小提琴 #2 这里.

我无法真正解释这个异常,您可能想在here向 Newtonsoft 提出问题。

© www.soinside.com 2019 - 2024. All rights reserved.