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

.NET 6 类型无关JSON序列化:PascalCase转camelCase方案问询

解决方案:ASP.NET 6中PascalCase配置转camelCase输出(无强类型)

由于JsonElement/JsonNode会保留原始JSON的属性命名,直接序列化无法触发camelCase命名策略,必须手动遍历并转换键名。以下是基于System.Text.Json的两种可行方案:

方案一:基于JsonNode递归转换

通过解析原始JSON为JsonDocument,递归遍历所有节点并转换属性名为camelCase,最后序列化处理后的JsonNode:

using System.Text.Json;
using System.Text.Json.Nodes;

public static class JsonCaseConverter
{
    public static string ConvertPascalToCamel(string pascalCaseJson)
    {
        using var doc = JsonDocument.Parse(pascalCaseJson);
        var camelCaseNode = TransformNodeToCamelCase(doc.RootElement);
        return JsonSerializer.Serialize(camelCaseNode, new JsonSerializerOptions 
        { 
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true // 可选,格式化输出
        });
    }

    private static JsonNode? TransformNodeToCamelCase(JsonElement element)
    {
        return element.ValueKind switch
        {
            JsonValueKind.Object => TransformObjectToCamelCase(element),
            JsonValueKind.Array => TransformArrayToCamelCase(element),
            _ => JsonNode.Parse(element.GetRawText())
        };
    }

    private static JsonObject TransformObjectToCamelCase(JsonElement element)
    {
        var camelCaseObj = new JsonObject();
        foreach (var prop in element.EnumerateObject())
        {
            var camelCaseName = JsonNamingPolicy.CamelCase.ConvertName(prop.Name);
            camelCaseObj[camelCaseName] = TransformNodeToCamelCase(prop.Value);
        }
        return camelCaseObj;
    }

    private static JsonArray TransformArrayToCamelCase(JsonElement element)
    {
        var camelCaseArray = new JsonArray();
        foreach (var item in element.EnumerateArray())
        {
            camelCaseArray.Add(TransformNodeToCamelCase(item));
        }
        return camelCaseArray;
    }
}

在ASP.NET 6控制器中使用

从配置读取JsonElement后转换输出:

[ApiController]
[Route("api/config")]
public class ConfigController : ControllerBase
{
    private readonly IConfiguration _config;

    public ConfigController(IConfiguration config)
    {
        _config = config;
    }

    [HttpGet]
    public IActionResult GetCamelCaseConfig()
    {
        // 读取目标配置节点为JsonElement
        var pascalCaseElement = _config.GetSection("YourTargetConfig").Get<JsonElement>();
        // 转为原始JSON字符串
        var pascalCaseJson = pascalCaseElement.GetRawText();
        // 转换为camelCase
        var camelCaseJson = JsonCaseConverter.ConvertPascalToCamel(pascalCaseJson);
        
        return Content(camelCaseJson, "application/json");
    }
}

方案二:基于Dictionary递归转换

如果偏好使用.NET通用集合,可反序列化为Dictionary<string, object>后递归转换键名:

using System.Text.Json;
using System.Collections.Generic;

public static class JsonCaseConverter
{
    public static string ConvertPascalToCamel(string pascalCaseJson)
    {
        var deserializeOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
        var pascalDict = JsonSerializer.Deserialize<Dictionary<string, object>>(pascalCaseJson, deserializeOptions);
        var camelDict = TransformDictToCamelCase(pascalDict);
        
        return JsonSerializer.Serialize(camelDict, new JsonSerializerOptions 
        { 
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        });
    }

    private static Dictionary<string, object> TransformDictToCamelCase(Dictionary<string, object> sourceDict)
    {
        var camelDict = new Dictionary<string, object>();
        foreach (var kvp in sourceDict)
        {
            var camelKey = JsonNamingPolicy.CamelCase.ConvertName(kvp.Key);
            
            if (kvp.Value is Dictionary<string, object> nestedDict)
            {
                camelDict[camelKey] = TransformDictToCamelCase(nestedDict);
            }
            else if (kvp.Value is List<object> arrayList)
            {
                var camelList = new List<object>();
                foreach (var item in arrayList)
                {
                    if (item is Dictionary<string, object> itemDict)
                    {
                        camelList.Add(TransformDictToCamelCase(itemDict));
                    }
                    else
                    {
                        camelList.Add(item);
                    }
                }
                camelDict[camelKey] = camelList;
            }
            else
            {
                camelDict[camelKey] = kvp.Value;
            }
        }
        return camelDict;
    }
}

关键说明

  • JsonElement/JsonNode的设计目标是精确映射原始JSON结构,因此直接序列化不会应用命名策略,必须手动转换键名。
  • 两种方案均支持嵌套对象和数组的转换,覆盖大多数未知结构的JSON场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:21:04