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

如何高效将含extension_前缀的JSON字段反序列化为.NET类的Dictionary属性

更优雅的解决方案:自动处理扩展字段的反序列化

嘿,你的手动遍历思路虽然可行,但确实有更简洁高效的方式——咱们可以利用Newtonsoft.Json的自定义扩展能力,在反序列化过程中自动识别extension_前缀的字段,直接存入extensions字典,不用额外写遍历逻辑。下面给你两种实用的实现方式:

方法一:自定义JsonConverter(针对性最强)

这个转换器会全程接管TargetClass的反序列化,帮你自动拆分常规字段和扩展字段:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

public class TargetClassConverter : JsonConverter<TargetClass>
{
    public override TargetClass ReadJson(JsonReader reader, Type objectType, TargetClass existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObj = JObject.Load(reader);
        var target = new TargetClass();

        // 映射JSON里的A/B/C到类的a/b/c属性(如果需要大小写严格匹配,可以给类属性加[JsonProperty("A")])
        target.a = jsonObj["A"]?.ToString();
        target.b = jsonObj["B"]?.ToString();
        target.c = jsonObj["C"]?.ToString();

        // 自动抓取所有extension_前缀的字段存入字典
        foreach (var prop in jsonObj.Properties())
        {
            if (prop.Name.StartsWith("extension_", StringComparison.OrdinalIgnoreCase))
            {
                target.extensions[prop.Name] = prop.Value?.ToString();
            }
        }

        return target;
    }

    // 如果需要把实例序列化回JSON,这里可以实现反向逻辑(可选)
    public override void WriteJson(JsonWriter writer, TargetClass value, JsonSerializer serializer)
    {
        var jsonObj = new JObject();
        jsonObj["A"] = value.a;
        jsonObj["B"] = value.b;
        jsonObj["C"] = value.c;

        foreach (var kvp in value.extensions)
        {
            jsonObj[kvp.Key] = kvp.Value;
        }

        jsonObj.WriteTo(writer);
    }
}

怎么用?

反序列化的时候指定这个转换器就行:

var json = @"{ ""id"": ""913678a9-63d6-4261-9a4c-d710755c8141"", ""A"": null, ""B"": null, ""C"": null, ""extension_A"": ""COKOLWIEK"", ""extension_B"": ""36402User"" }";

var settings = new JsonSerializerSettings();
settings.Converters.Add(new TargetClassConverter());

var result = JsonConvert.DeserializeObject<TargetClass>(json, settings);

方法二:自定义ContractResolver(全局生效)

如果你希望这个规则能在整个项目里通用,不用每次反序列化都加转换器,可以自定义契约解析器:

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Reflection;

public class ExtensionContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var prop = base.CreateProperty(member, memberSerialization);

        // 让extensions字典跳过常规序列化逻辑,交给我们的转换器处理
        if (member.Name == nameof(TargetClass.extensions))
        {
            prop.Ignored = true;
            return prop;
        }

        return prop;
    }

    protected override void ResolveContractConverter(Type objectType)
    {
        base.ResolveContractConverter(objectType);
        // 给TargetClass绑定我们的转换器
        if (objectType == typeof(TargetClass))
        {
            ContractConverter = new TargetClassConverter();
        }
    }
}

全局配置方式

把它设为默认设置,之后直接反序列化就行:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
    ContractResolver = new ExtensionContractResolver()
};

// 直接调用反序列化,不用再指定转换器
var result = JsonConvert.DeserializeObject<TargetClass>(json);

额外提示

  • JSON里的id字段你的类里没有对应属性,转换器会自动忽略它,完全符合你的需求
  • 如果想让类的a/b/c和JSON的A/B/C映射更规范,给类属性加上[JsonProperty("A")]特性就好,这样转换器里的字段名不用硬编码
  • 这种方式比手动遍历更符合职责分离,逻辑集中在转换器里,后续维护也更方便

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:19:11