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

如何全局配置JSON从蛇形命名到驼峰命名的反序列化

全局配置蛇形命名与驼峰命名的JSON序列化/反序列化规则

问题场景

需要反序列化如下蛇形命名的JSON响应:

{
    "result": [
        "......"
    ],
    "plugins_versions": {
        "age": "agegender.AgeDetector",
        "gender": "agegender.GenderDetector",
        "detector": "facenet.FaceDetector",
        "calculator": "facenet.Calculator"
    }
}

测试代码模拟反序列化过程(使用System.Text.Json):

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

var jsonOptions = new JsonSerializerOptions()
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};

var jsonString = "{\"plugins_versions\": {\"age\": \"agegender.AgeDetector\"}}";
Console.WriteLine(jsonString);
var parsedText = JsonSerializer.Deserialize<Response>(jsonString, options: jsonOptions);

Console.WriteLine(parsedText.PluginsVersions.Age);

class Response
{
    public PluginVersion PluginsVersions { get; set; }
}

class PluginVersion
{
    public string Age { get; set; }
}

设置PropertyNamingPolicy = JsonNamingPolicy.CamelCase后无法反序列化plugins_versions字段,仅手动添加[JsonPropertyName("plugins_versions")]特性才能成功。需要全局配置蛇形命名与Pascal命名(类属性的大驼峰)的转换规则,避免逐个字段添加特性。

问题原因

默认的JsonNamingPolicy.CamelCase仅支持Pascal命名与小驼峰命名的双向转换,无法识别蛇形命名(下划线分隔)的JSON字段。

你之前自定义的SnakeCaseToCamelCaseNamingPolicy逻辑方向错误:JsonNamingPolicy.ConvertName方法的作用是将.NET类的属性名转换为JSON字段名(序列化时),反序列化时则通过类属性名转换后的结果匹配JSON字段。而你的代码是把蛇形命名转成Pascal命名,与实际需求方向相反,因此不生效。

解决方案

编写正确的自定义命名策略,实现Pascal命名到蛇形命名的转换,这样序列化和反序列化时都能自动匹配:

1. 自定义命名策略类

using System.Text.Json;

namespace Test;

public class PascalToSnakeCaseNamingPolicy : JsonNamingPolicy
{
    public override string ConvertName(string name)
    {
        if (string.IsNullOrEmpty(name))
            return name;

        var result = new System.Text.StringBuilder();
        // 首字母转小写
        result.Append(char.ToLowerInvariant(name[0]));

        for (int i = 1; i < name.Length; i++)
        {
            // 遇到大写字母,先加下划线再转小写
            if (char.IsUpper(name[i]))
            {
                result.Append('_');
                result.Append(char.ToLowerInvariant(name[i]));
            }
            else
            {
                result.Append(name[i]);
            }
        }

        return result.ToString();
    }
}

2. 全局应用该策略

修改JsonSerializerOptions,使用自定义的命名策略:

using System.Text.Json;

var jsonOptions = new JsonSerializerOptions()
{
    PropertyNamingPolicy = new PascalToSnakeCaseNamingPolicy(),
    // 可添加其他配置,比如忽略null值
    // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

// 反序列化测试
var jsonString = "{\"plugins_versions\": {\"age\": \"agegender.AgeDetector\"}}";
var parsedText = JsonSerializer.Deserialize<Response>(jsonString, jsonOptions);
Console.WriteLine(parsedText.PluginsVersions.Age); // 输出:agegender.AgeDetector

// 序列化测试(自动转成蛇形命名JSON)
var response = new Response
{
    PluginsVersions = new PluginVersion { Age = "test_version" }
};
var serializedJson = JsonSerializer.Serialize(response, jsonOptions);
Console.WriteLine(serializedJson); // 输出:{"plugins_versions":{"age":"test_version"}}

class Response
{
    public PluginVersion PluginsVersions { get; set; }
}

class PluginVersion
{
    public string Age { get; set; }
}

逻辑说明

  • 该策略会将.NET类的Pascal命名属性(如PluginsVersions)转换为蛇形命名的JSON字段(plugins_versions)。
  • 反序列化时,.NET会自动将类属性名转换为蛇形命名,与JSON中的字段匹配,无需手动添加特性。
  • 序列化时,也会自动将类属性转成蛇形命名的JSON,实现双向统一的全局配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:01:11