您可以使用自定义
ContractResolver来执行此操作。基本上,这与
[JsonProperty]在每个要映射到其的类成员上将属性映射到不同JSON属性名称的想法相同,只是通过解析器以编程方式进行操作。在反序列化之前进行设置时,可以将所需映射的字典传递给解析器。
自定义解析器代码如下所示:
class DynamicMappingResolver : DefaultContractResolver{ private Dictionary<Type, Dictionary<string, string>> memberNameToJsonNameMap; public DynamicMappingResolver(Dictionary<Type, Dictionary<string, string>> memberNameToJsonNameMap) { this.memberNameToJsonNameMap = memberNameToJsonNameMap; } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty prop = base.CreateProperty(member, memberSerialization); Dictionary<string, string> dict; string jsonName; if (memberNameToJsonNameMap.TryGetValue(member.DeclaringType, out dict) && dict.TryGetValue(member.Name, out jsonName)) { prop.PropertyName = jsonName; } return prop; }}要使用解析器,请首先构造一个
Dictionary<Type, Dictionary<string,string>>包含您的映射的。外字典的键是您要映射其属性的类类型。内部字典是类属性名称到JSON属性名称的映射。您只需要为其名称与JSON不匹配的属性提供映射。
因此,例如,如果您的JSON如下所示(请注意
details对象内部属性的更改名称)…
{ "values": { "details": { "foo": "94", "bar": "47", "baz": "32", "quux": 1 }, count: 4 }}…并且您想将其映射到问题中的类,则可以这样创建字典:
var map = new Dictionary<Type, Dictionary<string, string>>{ { typeof(Details), new Dictionary<string, string> { {"property1", "foo"}, {"property2", "bar"}, {"property3", "baz"}, {"property4", "quux"} } }};最后一步是使用新的解析器实例设置序列化程序设置,为其提供刚刚构造的映射字典,然后将设置传递给
JsonConvert.DeserializeObject()。
var settings = new JsonSerializerSettings{ ContractResolver = new DynamicMappingResolver(map)};var root = JsonConvert.DeserializeObject<RootObject>(json, settings);这是一个演示:https :
//dotnetfiddle.net/ULkB0J



