You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#控制台程序JSON反序列化动态类型值报错求助

解决JSON中'value'属性同时支持字符串和数组的反序列化问题

问题根源:Newtonsoft.Json(Json.NET)中,object类型默认仅能反序列化JSON原始值(字符串、数字、布尔值等),无法直接处理JSON数组,因此出现报错。以下是三种可行解决方案:

方案1:用JsonElement兼容任意JSON类型

将CustomAttribute类中的Value类型改为JsonElement,它可以直接表示任何JSON类型(原始值、数组、对象等),是最直接的兼容方式:

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

    [JsonProperty("value")]
    public JsonElement Value { get; set; }
}

使用时通过ValueKind判断类型并提取数据:

foreach (var attr in response.CustomAttributes)
{
    if (attr.Value.ValueKind == JsonValueKind.String)
    {
        string singleValue = attr.Value.GetString();
        // 处理单字符串值逻辑
    }
    else if (attr.Value.ValueKind == JsonValueKind.Array)
    {
        var arrayValues = attr.Value.EnumerateArray()
                                   .Select(item => item.GetString())
                                   .ToList();
        // 处理数组值逻辑
    }
}

方案2:自定义JsonConverter统一处理两种类型

如果希望Value属性仍然用object接收,但自动区分字符串和数组,可编写自定义转换器:

自定义转换器实现

public class FlexibleValueConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(object);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        switch (reader.TokenType)
        {
            case JsonToken.String:
                return reader.Value.ToString();
            case JsonToken.StartArray:
                var stringList = new List<string>();
                while (reader.Read() && reader.TokenType != JsonToken.EndArray)
                {
                    if (reader.TokenType == JsonToken.String)
                    {
                        stringList.Add(reader.Value.ToString());
                    }
                }
                return stringList;
            default:
                return null;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

给属性添加转换器标记

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

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

使用时通过类型判断处理数据:

foreach (var attr in response.CustomAttributes)
{
    if (attr.Value is string singleVal)
    {
        // 处理单值
    }
    else if (attr.Value is List<string> arrayVal)
    {
        // 处理数组
    }
}

方案3:统一用List<string>接收(推荐)

如果业务上可以统一将值视为字符串列表,无论JSON是单值还是数组,都转成List<string>,这种方式最省心,无需额外判断:

自定义单值/数组转换器

public class SingleOrArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<T>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        return token.Type == JTokenType.Array 
            ? token.ToObject<List<T>>() 
            : new List<T> { token.ToObject<T>() };
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var list = value as List<T>;
        if (list?.Count == 1)
        {
            serializer.Serialize(writer, list[0]);
        }
        else
        {
            serializer.Serialize(writer, list);
        }
    }
}

修改CustomAttribute类

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

    [JsonProperty("value")]
    [JsonConverter(typeof(SingleOrArrayConverter<string>))]
    public List<string> Value { get; set; } = new List<string>();
}

这样无论JSON中value是单个字符串还是字符串数组,最终都会被反序列化为List<string>,单值会被自动包装成只有一个元素的列表,使用时直接遍历列表即可。


内容的提问来源于stack exchange,提问作者BryceBy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:03:33