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

