使用Newtonsoft反序列化JSON时无需JsonProperty移除下划线
问题
我有如下含下划线键名的JSON数据:
{"part_1":"","part_2":"","part_3":"","part_4":"","part_5":"","part_6":"","part_7":"","part_8":"","part_9":"","part_10":"","part_11":"","part_12":"","totalNum":"","ab_cd_ef":""}
希望将其反序列化为如下无下划线命名的C#实体类:
public partial class Welcome4 { public string Part1 { get; set; } public string Part2 { get; set; } public string Part3 { get; set; } // ……其余part_*属性省略 public int TotalNum { get; set; } public string Abcdef { get; set; } }
手动给每个属性加JsonProperty注解太繁琐,试过DefaultContractResolver但没找对方法,也试过正则替换JSON键名,想找更优方案。
解决方案
方法一:用Newtonsoft.Json(Json.NET)自定义契约解析器
直接继承DefaultContractResolver,重写ResolvePropertyName方法就能实现下划线到帕斯卡命名的自动映射,不用给每个属性加注解:
public class UnderscoreToPascalCaseResolver : DefaultContractResolver { protected override string ResolvePropertyName(string propertyName) { if (string.IsNullOrEmpty(propertyName)) return propertyName; var parts = propertyName.Split('_'); var result = new StringBuilder(); foreach (var part in parts) { if (string.IsNullOrEmpty(part)) continue; // 首字母大写,其余保持原样(比如totalNum自动转TotalNum) result.Append(char.ToUpper(part[0])).Append(part.Substring(1)); } return result.ToString(); } }
使用时在反序列化配置里指定这个解析器就行:
var settings = new JsonSerializerSettings { ContractResolver = new UnderscoreToPascalCaseResolver(), NullValueHandling = NullValueHandling.Ignore }; var json = "你的JSON字符串"; var welcomeObj = JsonConvert.DeserializeObject<Welcome4>(json, settings);
这个解析器会自动把JSON里的part_1、ab_cd_ef这类下划线键,映射到实体类的Part1、Abcdef属性,还能兼容totalNum这种混合命名的键转成TotalNum。
方法二:用System.Text.Json自定义命名策略
如果用的是.NET Core/.NET 5+自带的System.Text.Json,可以自定义JsonNamingPolicy来实现同样效果:
public class UnderscoreToPascalCaseNamingPolicy : JsonNamingPolicy { public override string ConvertName(string name) { if (string.IsNullOrEmpty(name)) return name; var parts = name.Split('_'); var result = new StringBuilder(); foreach (var part in parts) { if (string.IsNullOrEmpty(part)) continue; result.Append(char.ToUpper(part[0])).Append(part.Substring(1)); } return result.ToString(); } }
反序列化时配置这个命名策略:
var options = new JsonSerializerOptions { PropertyNamingPolicy = new UnderscoreToPascalCaseNamingPolicy(), IgnoreNullValues = true }; var json = "你的JSON字符串"; var welcomeObj = JsonSerializer.Deserialize<Welcome4>(json, options);
为啥这比正则替换好
- 不用修改原始JSON字符串,直接在序列化环节处理映射,逻辑更集中
- 支持复杂嵌套对象的自动映射,正则替换很难搞定多层嵌套的JSON结构
- 一次配置全局复用,所有实体类都能套用这个规则,不用重复写代码
内容的提问来源于stack exchange,提问作者Phonex Alica
相关产品推荐
相关产品推荐

