如何将JSON中单对象的item强制反序列化为List<Item>?
解决JSON单个对象反序列化为List的问题
问题场景
你的JSON结构中maqVeicEquip下的item是单个对象,但C#类里将item定义为List<Item>,导致反序列化失败。以下是几种直接可行的解决方法:
方法一:自定义Json转换器(Newtonsoft.Json)
如果项目使用Newtonsoft.Json(Json.NET),可以编写一个通用转换器,自动兼容单个对象和数组的情况:
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 switch { JTokenType.Array => token.ToObject<List<T>>(), JTokenType.Object => new List<T> { token.ToObject<T>() }, _ => throw new JsonSerializationException("无法转换为List<T>类型") }; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
然后在MaqVeicEquip类的item属性上标记该转换器:
public class MaqVeicEquip { [JsonConverter(typeof(SingleOrArrayConverter<Item>))] public List<Item> item { get; set; } public class Item { public string tipoMaq { get; set; } public string marca { get; set; } public string idadeMediaFrota { get; set; } public string quantidade { get; set; } public string indOnus { get; set; } public string valorMedio { get; set; } public string outrasInformacoes { get; set; } public string percPropriedade { get; set; } } }
反序列化时直接调用:
var result = JsonConvert.DeserializeObject<MaqVeicEquip>(jsonString);
方法二:自定义转换器(System.Text.Json)
如果使用.NET Core/.NET 5+自带的System.Text.Json,同样可以实现通用转换器:
public class SingleOrArrayConverter<T> : JsonConverter<List<T>> { public override List<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.StartObject) { var item = JsonSerializer.Deserialize<T>(ref reader, options); return new List<T> { item }; } else if (reader.TokenType == JsonTokenType.StartArray) { return JsonSerializer.Deserialize<List<T>>(ref reader, options); } throw new JsonException("JSON格式无效,无法转换为List<T>"); } public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }
两种使用方式:
- 属性标记:
public class MaqVeicEquip { [JsonConverter(typeof(SingleOrArrayConverter<Item>))] public List<Item> item { get; set; } // Item类定义不变 }
- 序列化选项注册:
var options = new JsonSerializerOptions(); options.Converters.Add(new SingleOrArrayConverter<MaqVeicEquip.Item>()); var result = JsonSerializer.Deserialize<MaqVeicEquip>(jsonString, options);
方法三:手动解析JSON结构
如果不想编写转换器,可以手动解析JSON并处理单个对象转列表的逻辑:
Newtonsoft.Json手动处理:
var jObj = JObject.Parse(jsonString); var maqVeicEquip = new MaqVeicEquip(); var itemToken = jObj["maqVeicEquip"]["item"]; if (itemToken.Type == JTokenType.Object) { maqVeicEquip.item = new List<MaqVeicEquip.Item> { itemToken.ToObject<MaqVeicEquip.Item>() }; } else if (itemToken.Type == JTokenType.Array) { maqVeicEquip.item = itemToken.ToObject<List<MaqVeicEquip.Item>>(); }
System.Text.Json手动处理:
using var doc = JsonDocument.Parse(jsonString); var root = doc.RootElement.GetProperty("maqVeicEquip"); var maqVeicEquip = new MaqVeicEquip(); var itemProp = root.GetProperty("item"); if (itemProp.ValueKind == JsonValueKind.Object) { var item = JsonSerializer.Deserialize<MaqVeicEquip.Item>(itemProp.GetRawText()); maqVeicEquip.item = new List<MaqVeicEquip.Item> { item }; } else if (itemProp.ValueKind == JsonValueKind.Array) { maqVeicEquip.item = JsonSerializer.Deserialize<List<MaqVeicEquip.Item>>(itemProp.GetRawText()); }
内容的提问来源于stack exchange,提问作者Maxwell
相关产品推荐
相关产品推荐

