如何使Json.Net跳过空集合的序列化 [英] How to make Json.Net skip serialization of empty collections

查看:95
本文介绍了如何使Json.Net跳过空集合的序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an object that contains several properties that are a List of strings List<String> or a dictionary of strings Dictionary<string,string>. I want to serialize the object to json using Json.net and I want to have the least amount of text generated.

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

I am using the DefaultValueHandling and NullValueHandling to set default values to strings and integers. But how can I define the DefaultValueHandling to ignore the property in the serialized output if it is initialized to an empty List<String> or Dictionary<string,string>?

一些示例输出是:

{
 "Value1": "my value",
 "Value2": 3,
 "List1": [],
 "List2": []
}

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

I want to get a result that ignores the two lists in the above example, because they are set to the default value of an empty list.

任何帮助将不胜感激

推荐答案

我已经在

I have implemented this feature in the custom contract resolver of my personal framework (link to the specific commit in case the file will be moved later). It uses some helper methods and includes some unrelated code for custom references syntax. Without them, the code will be:

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;
    }
}

除非为属性或字段指定了DefaultValueHandling.Include,否则该合同解析器将跳过所有空集合(所有实现ICollection并具有Length == 0的类型)的序列化.

This contract resolver will skip serialization of all empty collections (all types implementing ICollection and having Length == 0), unless DefaultValueHandling.Include is specified for the property or the field.

这篇关于如何使Json.Net跳过空集合的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆