如何使Json.Net跳过空集合的序列化

aga*_*ian 9 c# asp.net serialization json.net

我有一个对象,其中包含几个属性,这些属性是字符串列表List<String>或字符串字典Dictionary<string,string>.我想使用Json.net将对象序列化为json,我希望生成最少量的文本.

我使用DefaultValueHandling和NullValueHandling将默认值设置为字符串和整数.但是,如果将DefaultValueHandling初始化为空List<String>Dictionary<string,string>?,则如何定义DefaultValueHandling以忽略序列化输出中的属性?

一些示例输出是:

{
 "Value1": "my value",
 "Value2": 3,
 "List1": [],
 "List2": []
}
Run Code Online (Sandbox Code Playgroud)

我想得到一个忽略上例中两个列表的结果,因为它们被设置为空列表的默认值.

任何帮助将不胜感激

Ath*_*ari 16

我已经在我的个人框架的自定义合约解析器中实现了此功能(如果文件稍后将被移动,则链接到特定的提交).它使用一些辅助方法,并包含一些不相关的自定义引用语法代码.没有它们,代码将是:

public class SkipEmptyContractResolver : DefaultContractResolver
{
    public SkipEmptyContractResolver (bool shareCache = false) : base(shareCache) { }

    protected override JsonProperty CreateProperty (MemberInfo member,
            MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);
        bool isDefaultValueIgnored =
            ((property.DefaultValueHandling ?? DefaultValueHandling.Ignore)
                & DefaultValueHandling.Ignore) != 0;
        if (isDefaultValueIgnored
                && !typeof(string).IsAssignableFrom(property.PropertyType)
                && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) {
            Predicate<object> newShouldSerialize = obj => {
                var collection = property.ValueProvider.GetValue(obj) as ICollection;
                return collection == null || collection.Count != 0;
            };
            Predicate<object> oldShouldSerialize = property.ShouldSerialize;
            property.ShouldSerialize = oldShouldSerialize != null
                ? o => oldShouldSerialize(o) && newShouldSerialize(o)
                : newShouldSerialize;
        }
        return property;
    }
}
Run Code Online (Sandbox Code Playgroud)

除非为属性或字段指定,否则此合约解析程序将跳过所有空集合(实现ICollection和拥有的所有类型Length == 0)的序列化DefaultValueHandling.Include.


Dej*_*jan 8

另一个非常简单的解决方案是ShouldSerialize*此处按序列化的类型实现方法.

如果您控制要序列化的类型并且它不是您想要引入的一般行为,那么这可能是首选方法.