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

实现支持单个对象与对象列表的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:01:18