如何使 DefaultValueHandling 仅适用于某些类或成员?

Posted

技术标签:

【中文标题】如何使 DefaultValueHandling 仅适用于某些类或成员?【英文标题】:How to make DefaultValueHandling only apply to certain classes or members? 【发布时间】:2021-07-29 14:24:49 【问题描述】:

我需要让对象的某些部分序列化默认值,而有些则不需要。

在下面的帖子中,我了解如何根据类型执行此操作: Json.NET: How to make DefaultValueHandling only apply to certain types?

但是这个解决方案只适用于类型,不会递归。

预期行为:


  
    "keepDefaults" : 
      "prop1" : true,
      "prop2" : false,
    ,
    "ignoreDefaults" : 
      "prop3" : true,
      "prop4" : false,
    

重新序列化时:

  
    "keepDefaults" : 
      "prop1" : true,
      "prop2" : false
    ,
    "ignoreDefaults" : 
      "prop3" : true
    

有什么我可以在 ContractProvider 中覆盖的东西,或者我可以添加到成员或类中以选择 DefaultValueHandling 的属性吗?

【问题讨论】:

这能回答你的问题吗? Default value for missing properties with JSON.net @Sinatr 不是真的,因为我需要将 JsonProperty 属性添加到 ignoreDefaults 类或 keepDefaults 类的每个属性中 【参考方案1】:

受到@dbc 在quoted post 中的解决方案的启发,我对其进行了调整,以将 DefaultValueHandling 应用于整个类。

public class DefaultValueContractResolver : DefaultContractResolver

    readonly Dictionary<Type, DefaultValueHandling> _overrides = new Dictionary<Type, DefaultValueHandling>();

    public DefaultValueContractResolver(IEnumerable<KeyValuePair<Type, DefaultValueHandling>> overrides = null) : base()
    
        _overrides = overrides?.ToDictionary(p => p.Key, p => p.Value) ?? _overrides;
    

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    
        var property = base.CreateProperty(member, memberSerialization);
        if (property.DefaultValueHandling == null)
        
            if(_overrides.TryGetValue(property.DeclaringType, out DefaultValueHandling handling))
                property.DefaultValueHandling = handling;
        
    
        return property;
    

那我可以这样序列化:

var keepDefaults = new KeepDefaults

    Prop1 = true,
    Prop2 = false
;

var ignoreDefaults = new IgnoreDefaults

    Prop3 = true,
    Prop4 = false
;

var jsSettings = new JsonSerializerSettings

    //DefaultValueHandling = DefaultValueHandling.Populate,
    ContractResolver = new DefaultValueContractResolver(
        new Dictionary<Type, DefaultValueHandling>
         
             typeof(IgnoreDefaults), DefaultValueHandling.Ignore  ,
             typeof(KeepDefaults), DefaultValueHandling.Populate  
        ),
    Converters = new List<JsonConverter>  new Newtonsoft.Json.Converters.StringEnumConverter() ,
    Formatting = Formatting.Indented
;



var json1 = JsonConvert.SerializeObject(keepDefaults, settings);
var json2 = JsonConvert.SerializeObject(ignoreDefaults, settings);

瞧,我得到了预期的结果。

【讨论】:

以上是关于如何使 DefaultValueHandling 仅适用于某些类或成员?的主要内容,如果未能解决你的问题,请参考以下文章

Json转换空字符串而不是null

VB中如何使RICHTEXTBOX透明

mfc 如何使窗口居中

如何使 RelativeLayout 半透明但不使活动

如何用word使图片上下居中

如何使图像自动调整大小,使宽度为 100% 并相应调整高度?