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
相关产品推荐
相关产品推荐

