如何强制System.Text.Json以CamelCase规则反序列化PascalCase JSON
为什么你的代码没有生效
System.Text.Json 中的PropertyNamingPolicy、DictionaryKeyPolicy配置仅作用于强类型POCO类、字典类型的序列化/反序列化流程。当你直接操作JsonElement这类通用JSON节点类型时,框架会原封不动保留原始JSON的属性名,不会触发任何命名转换逻辑,这是框架的设计行为,所以你尝试的直接反序列化、「反序列化-序列化-再反序列化」的流程都不会生效。
可行实现方案
你可以通过递归遍历JSON节点、主动转换属性名的方式实现需求,以下是可直接复用的实现代码:
方案1:预定义转换方法处理已反序列化的JsonElement
using System.Text.Json; using System.Text.Json.Nodes; public static JsonElement ConvertToCamelCaseJsonElement(JsonElement original) { var jsonNode = JsonNode.Parse(original.GetRawText()); ConvertNodeToCamelCase(jsonNode); return jsonNode.Deserialize<JsonElement>(); } private static void ConvertNodeToCamelCase(JsonNode node) { if (node is JsonObject obj) { // 先收集所有原始属性,再替换为驼峰命名 var originalProperties = obj.ToList(); obj.Clear(); foreach (var prop in originalProperties) { var camelName = JsonNamingPolicy.CamelCase.ConvertName(prop.Key); ConvertNodeToCamelCase(prop.Value); obj[camelName] = prop.Value; } } else if (node is JsonArray arr) { // 遍历数组内所有节点处理 foreach (var item in arr) { ConvertNodeToCamelCase(item); } } // JsonValue类型不需要处理属性名,直接跳过 }
使用示例
var jsonString = "{\"Property1\":\"s\", \"PropertyCamel\":{\"PropertyNested\":\"g\"}, \"PPP\":[{\"NestedList\":\"1\"}]}"; var originalDeserialized = JsonSerializer.Deserialize<JsonElement>(jsonString); // 转换为驼峰命名的JsonElement var camelCaseElement = ConvertToCamelCaseJsonElement(originalDeserialized);
转换后属性名会全部符合驼峰命名约定:property1、propertyCamel、propertyNested、ppp、nestedList。
方案2:自定义JsonConverter在反序列化阶段直接转换
如果你希望在反序列化时直接得到驼峰命名的JsonElement,可以实现自定义转换器:
public class CamelCaseJsonElementConverter : JsonConverter<JsonElement> { public override JsonElement Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var node = JsonNode.Parse(ref reader); ConvertNodeToCamelCase(node); return node.Deserialize<JsonElement>(); } public override void Write(Utf8JsonWriter writer, JsonElement value, JsonSerializerOptions options) { value.WriteTo(writer); } private static void ConvertNodeToCamelCase(JsonNode node) { if (node is JsonObject obj) { var originalProps = obj.ToList(); obj.Clear(); foreach (var prop in originalProps) { var camelName = JsonNamingPolicy.CamelCase.ConvertName(prop.Key); ConvertNodeToCamelCase(prop.Value); obj[camelName] = prop.Value; } } else if (node is JsonArray arr) { foreach (var item in arr) { ConvertNodeToCamelCase(item); } } } }
使用示例
var options = new JsonSerializerOptions { Converters = { new CamelCaseJsonElementConverter() } }; var camelCaseElement = JsonSerializer.Deserialize<JsonElement>(jsonString, options);
内容的提问来源于stack exchange,提问作者Vitor Durante
相关产品推荐
相关产品推荐

