System.Text.Json反序列化字典遇空数组报错问题求助
解决方案
针对API返回字段类型不一致(有数据时是字典、无数据时是空数组)导致的System.Text.Json反序列化异常,你可以通过自定义JSON转换器来处理这种情况:
1. 实现自定义JSON转换器
这个转换器会自动识别空数组并转为空字典,遇到正常对象则按字典反序列化:
using System.Text.Json; using System.Text.Json.Serialization; public class DictionaryOrEmptyArrayConverter<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>> where TKey : notnull { public override Dictionary<TKey, TValue>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 处理空数组情况 if (reader.TokenType == JsonTokenType.StartArray) { reader.Skip(); return new Dictionary<TKey, TValue>(); } // 处理正常字典对象情况 else if (reader.TokenType == JsonTokenType.StartObject) { return JsonSerializer.Deserialize<Dictionary<TKey, TValue>>(ref reader, options); } // 其他异常类型抛出错误 throw new JsonException($"无法将JSON值转换为Dictionary<{typeof(TKey).Name}, {typeof(TValue).Name}>"); } public override void Write(Utf8JsonWriter writer, Dictionary<TKey, TValue> value, JsonSerializerOptions options) { // 序列化时按正常字典处理 JsonSerializer.Serialize(writer, value, options); } }
2. 在模型属性上绑定转换器
修改BookingIndexObj类,给目标属性添加转换器特性:
public class BookingIndexObj { public BookingRequestObj Request { get; set; } [JsonPropertyName("booking/index")] [JsonConverter(typeof(DictionaryOrEmptyArrayConverter<string, BookingIndexIndexObj>))] public Dictionary<string, BookingIndexIndexObj> BookingIndex { get; set; } }
3. 可选:通过序列化配置注入转换器
如果不想修改模型,也可以在反序列化时传入配置好的JsonSerializerOptions:
var options = new JsonSerializerOptions(); options.Converters.Add(new DictionaryOrEmptyArrayConverter<string, BookingIndexIndexObj>()); var bookingIndex = await httpClient.GetFromJsonAsync<BookingIndexObj>( $"booking/index?start_date={startDate.ToString("yyyy-MM-dd")}&end_date={endDate.ToString("yyyy-MM-dd")}", options);
这样处理后,API返回空数组时会自动转为空字典,有数据时正常反序列化为字典,不会再抛出类型转换异常。
内容的提问来源于stack exchange,提问作者Kaare Mai
相关产品推荐
相关产品推荐

