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
相关产品推荐
相关产品推荐

