如何使用JSON.Net将两种不同结构的JSON反序列化为同一个类?
实现方案
完全可以用Json.NET(Newtonsoft.Json)实现该需求,以下是两种常用实现方法:
方法1:使用JsonProperty的AlternateNames属性(推荐,适配Json.NET v12.0.1及以上版本)
你只需要修改原有Food类的JsonProperty注解,添加别名配置即可同时匹配两种JSON的键名:
public class Food { // 主映射键为"f",同时添加别名"Fruit"匹配数据源A的键名 [JsonProperty("f", AlternateNames = new []{"Fruit"})] public string Fruit { get; set; } }
反序列化测试代码:
using Newtonsoft.Json; // 数据源A的JSON string jsonA = "{\"Fruit\":\"Apple\"}"; // 数据源B的JSON string jsonB = "{\"f\":\"Apple\"}"; // 两种JSON都可以正常反序列化得到Fruit属性为Apple的Food实例 Food foodA = JsonConvert.DeserializeObject<Food>(jsonA); Food foodB = JsonConvert.DeserializeObject<Food>(jsonB);
方法2:自定义ContractResolver(适配低版本Json.NET,适合批量处理多别名映射场景)
如果你的Json.NET版本低于12.0.1不支持AlternateNames,可以通过自定义属性解析器实现多键名映射:
第一步:实现自定义解析器
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Reflection; public class MultiJsonPropertyNameResolver : DefaultContractResolver { protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); // 针对Food类的Fruit属性,配置匹配的JSON键名 if (member.DeclaringType == typeof(Food) && member.Name == nameof(Food.Fruit)) { // 优先匹配"f",找不到则匹配"Fruit" property.PropertyName = "f"; property.AlternateNames.Add("Fruit"); } return property; } }
第二步:反序列化时指定解析器配置
var deserializeSettings = new JsonSerializerSettings { ContractResolver = new MultiJsonPropertyNameResolver() }; // 两种JSON都可以正常反序列化 Food foodA = JsonConvert.DeserializeObject<Food>(jsonA, deserializeSettings); Food foodB = JsonConvert.DeserializeObject<Food>(jsonB, deserializeSettings);
内容的提问来源于stack exchange,提问作者John Livermore
相关产品推荐
相关产品推荐

