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

C#反序列化时如何将JSON前三个字符串数组动态属性映射到指定类并支持父对象反序列化

需求实现方案

该需求完全可以实现,最优方案是为FirstThreeRandomProperties实现自定义JSON反序列化转换器,将转换器直接挂载到目标类上,即可在ParentObject整体反序列化时自动触发映射逻辑,全程不需要手动拆分、填充extraProperties的内容。

核心实现逻辑

  • 利用System.Text.Json内置的JsonConverter机制,直接替换FirstThreeRandomProperties的默认反序列化规则
  • 依赖Utf8JsonReader的流式读取特性,严格保留JSON属性的出现顺序,不会打乱原始顺序
  • 读取过程中按顺序收集最多3个字符串数组值,超过3个的属性直接跳过不处理
  • 按收集顺序将值依次映射到extras1/extras2/extras3,收集数量不足3个时对应字段自动保持null

具体代码实现

1. 标记目标类使用自定义转换器

直接在FirstThreeRandomProperties类上添加转换器特性,让所有涉及该类的反序列化流程自动应用规则:

using System.Text.Json.Serialization;

// 挂载自定义转换器
[JsonConverter(typeof(FirstThreeRandomPropertiesConverter))]
public class FirstThreeRandomProperties
{
   public List<string> extras1;
   public List<string> extras2;
   public List<string> extras3;
}

public class ParentObject
{
   // 其他业务属性保持原有定义即可
   public FirstThreeRandomProperties extraProperties;
}

2. 实现自定义转换器逻辑

using System.Text.Json;
using System.Text.Json.Serialization;

public class FirstThreeRandomPropertiesConverter : JsonConverter<FirstThreeRandomProperties>
{
    public override FirstThreeRandomProperties Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 校验JSON结构合法性
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("extraProperties字段必须是JSON对象结构");

        var result = new FirstThreeRandomProperties();
        // 最多收集3个数组值
        var collectedArrays = new List<List<string>>(capacity: 3);

        // 流式遍历对象内所有属性,严格按JSON原始出现顺序读取
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
                break;

            // 动态属性名不需要匹配,直接解析属性值为字符串数组
            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                var arrayValue = JsonSerializer.Deserialize<List<string>>(ref reader, options);
                // 收集满3个后,后续属性直接跳过不做存储
                if (collectedArrays.Count < 3)
                {
                    collectedArrays.Add(arrayValue);
                }
            }
        }

        // 按顺序映射到对应字段,不足3个的字段保留null
        result.extras1 = collectedArrays.Count > 0 ? collectedArrays[0] : null;
        result.extras2 = collectedArrays.Count > 1 ? collectedArrays[1] : null;
        result.extras3 = collectedArrays.Count > 2 ? collectedArrays[2] : null;

        return result;
    }

    // 实现序列化逻辑,保证输出结构匹配类定义
    public override void Write(Utf8JsonWriter writer, FirstThreeRandomProperties value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("extras1");
        JsonSerializer.Serialize(writer, value.extras1, options);
        writer.WritePropertyName("extras2");
        JsonSerializer.Serialize(writer, value.extras2, options);
        writer.WritePropertyName("extras3");
        JsonSerializer.Serialize(writer, value.extras3, options);
        writer.WriteEndObject();
    }
}

验证效果

完成配置后,直接对包含extraProperties的ParentObject做整体反序列化即可:

// 正常反序列化,不需要额外处理
var parentObj = JsonSerializer.Deserialize<ParentObject>(inputJson);

以示例中的JSON结构为例:

{
   "extraProperties": {
       "unknownName1": [ "A" ],
       "unknownName2": [ "A", "B", "C" ]
   }
}

反序列化得到的parentObj.extraProperties将完全符合预期:

  • extras1 值为 ["A"]
  • extras2 值为 ["A", "B", "C"]
  • extras3 值为 null
  • 若extraProperties对象内存在第4个、第5个动态属性,会在读取过程中直接跳过,不会被存储到结果中。

内容的提问来源于stack exchange,提问作者Hradek1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 14:15:04