实现支持单个对象与对象列表的JsonConverter遇问题求助
解决方案:处理单个APIEntity与列表的反序列化及Properties转换器修复
你当前的MyCustomClassPropertiesJsonConverter负责properties字段的字符串与字典互转,但存在几处错误可能导致列表反序列化失败;同时你需要实现能同时处理单个APIEntity和其列表的反序列化逻辑,以下是具体修复方案:
一、修复Properties字段的转换器
1. 修正Write方法的错误
当前Write方法错误地将properties包裹为对象,且Trim操作未生效,修改后如下:
public override void Write( Utf8JsonWriter writer, Dictionary<string, string> dictionary, JsonSerializerOptions options) { string propertiesValue = ""; foreach ((string key, string value) in dictionary) { propertiesValue += $"{key}={value}|"; } // 修复Trim赋值问题,确保移除末尾的| propertiesValue = propertiesValue.Trim('|'); // 直接写入字符串,无需额外对象包裹 writer.WriteStringValue(propertiesValue); }
2. 增强Read方法的健壮性
当前Read方法未处理propertyItem不含=的情况,会抛出索引越界异常,增加校验逻辑:
public override Dictionary<string, string> Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.String) { throw new JsonException("properties字段必须是字符串类型"); } var dictionary = new Dictionary<string, string>(); string propertiesValue = reader.GetString(); if(string.IsNullOrEmpty(propertiesValue)) { return dictionary; // 返回空字典更健壮,也可根据需求抛出异常 } var propertiesItems = propertiesValue.Split('|', StringSplitOptions.RemoveEmptyEntries); foreach (var propertyItem in propertiesItems) { // 限制分割次数为2,避免值中包含=的情况 var item = propertyItem.Split('=', 2); if (item.Length != 2) { // 可选择忽略无效项或抛出异常 continue; // throw new JsonException($"无效的properties项格式:{propertyItem}"); } // 增加Trim处理键值对的空格 dictionary.Add(item[0].Trim(), item[1].Trim()); } return dictionary; }
二、实现单个对象/列表的通用反序列化转换器
如果需要同一逻辑既能处理单个APIEntity,也能处理List<APIEntity>,编写如下转换器:
public class APIEntityListConverter : JsonConverter<List<APIEntity>> { public override List<APIEntity> Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 若JSON是单个对象,转为包含该对象的列表 if (reader.TokenType == JsonTokenType.StartObject) { var entity = JsonSerializer.Deserialize<APIEntity>(ref reader, options); return new List<APIEntity> { entity }; } // 若JSON是数组,直接反序列化为列表 else if (reader.TokenType == JsonTokenType.StartArray) { return JsonSerializer.Deserialize<List<APIEntity>>(ref reader, options); } else { throw new JsonException("JSON格式不是单个对象或数组"); } } public override void Write( Utf8JsonWriter writer, List<APIEntity> value, JsonSerializerOptions options) { // 默认序列化数组,若需单个元素时序列化对象可自行修改逻辑 JsonSerializer.Serialize(writer, value, options); } }
使用转换器
反序列化时传入包含转换器的配置:
var options = new JsonSerializerOptions(); options.Converters.Add(new APIEntityListConverter()); options.Converters.Add(new MyCustomClassPropertiesJsonConverter()); // 无论API返回单个对象还是数组,都能得到List<APIEntity>结果 var entityList = await response.Content.ReadFromJsonAsync<List<APIEntity>>(options);
内容的提问来源于stack exchange,提问作者Gordon Gudmundson
相关产品推荐
相关产品推荐

