反序列化时如何优先设置VeryImportantProperty属性的值?
失效原因
你的代码无法生效的核心原因是:VeryImportantProperty按照设计不需要序列化,大概率被标记了[JsonIgnore]特性,或是默认被契约解析器标记为忽略状态,base.CreateProperty返回的JsonProperty.Ignored属性为true,Json.NET会直接跳过该属性的所有处理逻辑,你后续设置的默认值、排序规则都不会被执行。
解决方案
方案1:修正原有ContractResolver逻辑
调整CreateProperty方法,先解除属性的忽略标记,同时设置序列化时过滤该属性,避免序列化时输出:
public class MyContractResolver : DefaultContractResolver { public VeryImportantClass VeryImportantPropertyValue { get; set; } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); if (property.PropertyName == "VeryImportantProperty" && VeryImportantPropertyValue != null) { // 解除属性的忽略标记,让反序列化逻辑可以处理该属性 property.Ignored = false; // 设置序列化时永远不输出该属性,符合不需要序列化的设计要求 property.ShouldSerialize = _ => false; property.DefaultValue = VeryImportantPropertyValue; property.DefaultValueHandling = DefaultValueHandling.Populate; // 保证该属性最先被赋值 property.Order = -1; } return property; } }
方案2(更推荐):用反序列化回调赋值
直接在反序列化对象创建完成、属性赋值前的回调阶段注入赋值逻辑,不需要修改属性的序列化规则,稳定性更高:
public class MyContractResolver : DefaultContractResolver { public VeryImportantClass VeryImportantPropertyValue { get; set; } protected override JsonObjectContract ResolveObjectContract(Type type) { var contract = base.ResolveObjectContract(type); // 仅对包含VeryImportantProperty的目标类做处理,可根据实际需求补充类型过滤逻辑 var targetProp = type.GetProperty("VeryImportantProperty"); if (targetProp != null && VeryImportantPropertyValue != null) { // 注册反序列化前置回调,在所有属性赋值前执行 contract.OnDeserializingCallbacks.Add((instance, context) => { targetProp.SetValue(instance, VeryImportantPropertyValue); }); } return contract; } }
使用方式
反序列化时传入配置好的自定义ContractResolver即可:
var deserializeSettings = new JsonSerializerSettings { ContractResolver = new MyContractResolver { VeryImportantPropertyValue = 你要赋值的VeryImportantClass实例 } }; var targetObj = JsonConvert.DeserializeObject<你的目标类>(json字符串, deserializeSettings);
内容的提问来源于stack exchange,提问作者Andrey Golubev
相关产品推荐
相关产品推荐

