如何用Json.NET指定部分属性为驼峰格式并保留其他属性大小写
解决Newtonsoft.JSON混合大小写序列化需求
你的需求很明确:把Message类的Header和Body属性名转成驼峰格式,但Body内部的对象保留原有属性大小写,直接用默认的CamelCasePropertyNamesContractResolver做不到——它会递归把所有嵌套对象的属性都转成驼峰。这里有两种简单的实现方式,选哪种都可以:
方法一:给Body属性添加自定义JsonConverter
这种方式最直观,只需要给Message类的Body属性标记一个转换器,让它用默认规则序列化,而Message的其他属性用驼峰规则。
步骤1:定义自定义转换器
public class DefaultSerializationConverter : JsonConverter { // 判断是否可以转换目标类型(这里我们处理所有类型) public override bool CanConvert(Type objectType) => true; // 如果需要反序列化,这里可以补充实现逻辑(不需要的话直接抛出异常即可) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException("反序列化逻辑需要的话请自行实现"); } // 序列化时使用默认的JsonSerializer,不应用驼峰命名 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var defaultSerializer = new JsonSerializer(); defaultSerializer.Serialize(writer, value); } }
步骤2:修改Message类,给Body属性加标记
class Message { public HeaderType Header { get; set; } // 添加特性,指定用自定义转换器序列化Body [JsonConverter(typeof(DefaultSerializationConverter))] public object Body { get; set; } }
步骤3:序列化时使用驼峰规则
var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), Formatting = Formatting.Indented // 可选,让JSON格式更美观 }; var result = new Message() { Header = myHeader, Body = new SomeClass() { A = 1 } }; var json = JsonConvert.SerializeObject(result, settings);
最终输出的JSON会是你想要的格式:
{ "header": { // myHeader的属性会被转成驼峰,比如RequestId→requestId }, "body": { "A": 1 // 保留原属性名 } }
方法二:自定义ContractResolver(适合复杂场景)
如果你的项目里有很多类似的混合序列化需求,自定义ContractResolver会更灵活,不需要给每个属性加标记。
步骤1:定义自定义ContractResolver
public class MixedCaseContractResolver : CamelCasePropertyNamesContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 核心逻辑:仅对Message类的属性应用驼峰命名,其他类的属性保留原名称 // 这样Message的Header/Body会转成驼峰,Body内部对象的属性保持原样,Header内部对象的属性也会转成驼峰 if (member.DeclaringType != typeof(Message)) { property.PropertyName = member.Name; } return property; } }
步骤2:序列化时使用自定义ContractResolver
var settings = new JsonSerializerSettings { ContractResolver = new MixedCaseContractResolver(), Formatting = Formatting.Indented }; var json = JsonConvert.SerializeObject(result, settings);
两种方法都能实现你的需求,方法一更适合单一场景,方法二更适合批量处理类似规则的序列化需求。
内容的提问来源于stack exchange,提问作者pushkin
相关产品推荐
相关产品推荐

