C# Json.NET如何仅反序列化用JsonProperty别名,序列化用原属性名
需求说明
使用Json.NET(Newtonsoft.Json)处理JSON时,需要实现以下逻辑:
- 反序列化传入的JSON数据时,通过
[JsonProperty]特性配置的别名完成字段映射 - 执行序列化操作时,忽略
[JsonProperty]指定的别名,输出C#类的原生属性名
示例类定义如下:
public class DocumentDetail { [JsonProperty("KAREKOD")] public string qrCode { get; set; } [JsonProperty("GTIN")] public string gtinNumber { get; set; } [JsonProperty("LOTNUMBER")] public string lotNumber { get; set; } }
待序列化对象:
DocumentDetail docDetail = new DocumentDetail() { qrCode = "123456adsfg789", gtinNumber = "123asdf548654", lotNumber = "1231231sdfg23" };
预期序列化输出:
{ "qrCode" : "123456adsfg789", "gtinNumber" : "123asdf548654", "lotNumber" : "1231231sdfg23" }
实现方法
默认情况下[JsonProperty]配置的别名会同时生效于序列化和反序列化流程,我们可以通过自定义契约解析器,单独修改序列化阶段的属性名生成规则,不需要改动现有实体类的特性配置。
- 首先定义自定义契约解析器:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Reflection; public class DeserializeOnlyJsonPropertyResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member, memberSerialization); // 序列化阶段强制使用C#类原生属性名,忽略JsonProperty配置的别名 property.PropertyName = member.Name; return property; } }
- 序列化时传入带该解析器的配置即可,反序列化保持原有默认配置就能正常识别别名:
// 反序列化:默认配置即可自动识别KAREKOD/GTIN/LOTNUMBER别名映射 string inputJson = "{\"KAREKOD\":\"testQR\",\"GTIN\":\"testGTIN\",\"LOTNUMBER\":\"testLot\"}"; DocumentDetail parsedData = JsonConvert.DeserializeObject<DocumentDetail>(inputJson); // 序列化:使用自定义解析器,输出原生属性名 JsonSerializerSettings settings = new JsonSerializerSettings { ContractResolver = new DeserializeOnlyJsonPropertyResolver(), Formatting = Formatting.Indented }; string outputJson = JsonConvert.SerializeObject(docDetail, settings);
执行后输出的JSON和预期结果完全一致。
补充说明
- 该方案不会影响反序列化逻辑,
[JsonProperty]上配置的其他规则(如必填校验、空值处理等)依然正常生效 - 如果项目全局需要该行为,可以将自定义解析器注册到全局序列化配置中,无需每次序列化单独传参
内容的提问来源于stack exchange,提问作者Onur GOZ
相关产品推荐
相关产品推荐

