簡體   English   中英

使用Json.NET進行序列化時如何省略空集合

[英]How to omit empty collections when serializing with Json.NET

我正在使用Newtonsoft的Json.NET 7.0.0.0將類從C#序列化為JSON:

class Foo
{
    public string X;
    public List<string> Y = new List<string>();
}

var json =
    JsonConvert.SerializeObject(
        new Foo(),
        Formatting.Indented,
        new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

這里json的價值是

{ "Y": [] }

但如果Y是一個空列表,我希望它是{ }

我找不到一個令人滿意的方法來實現這一目標。 也許有自定義合約解析?

如果您正在尋找一種可以在不同類型中使用的解決方案,並且不需要任何修改(屬性等),那么我認為最好的解決方案是自定義DefaultContractResolver類。 它將使用反射來確定給定類型的任何IEnumerable是否為空。

public class IgnoreEmptyEnumerablesResolver : DefaultContractResolver
{
    public static readonly IgnoreEmptyEnumerablesResolver Instance = new IgnoreEmptyEnumerablesResolver();

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (property.PropertyType != typeof(string) &&
            typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
        {
            property.ShouldSerialize = instance =>
            {
                IEnumerable enumerable = null;

                // this value could be in a public field or public property
                switch (member.MemberType)
                {
                    case MemberTypes.Property:
                        enumerable = instance
                            .GetType()
                            .GetProperty(member.Name)
                            .GetValue(instance, null) as IEnumerable;
                        break;
                    case MemberTypes.Field:
                        enumerable = instance
                            .GetType()
                            .GetField(member.Name)
                            .GetValue(instance) as IEnumerable;
                        break;
                    default:
                        break;

                }

                if (enumerable != null)
                {
                    // check to see if there is at least one item in the Enumerable
                    return enumerable.GetEnumerator().MoveNext();
                }
                else
                {
                    // if the list is null, we defer the decision to NullValueHandling
                    return true;
                }

            };
        }

        return property;
    }
}

如果您可以修改類,則可以添加Shrink方法並為所有空集合設置null。 它需要更改類,但它具有更好的性能。 只是另一種選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM