How to omit empty collections when serializing with Json.NET

前端 未结 2 570
渐次进展
渐次进展 2021-01-08 00:36

I\'m using Newtonsoft\'s Json.NET 7.0.0.0 to serialize classes to JSON from C#:

class Foo
{
    public string X;
    public List Y = new List&l         


        
相关标签:
2条回答
  • 2021-01-08 00:40

    If you can modify your classes, you could add Shrink method and set null for all empty collections. It requires to change the class but it has better performance. Just another option for you.

    0 讨论(0)
  • 2021-01-08 00:52

    If you're looking for a solution which can be used generically across different types and does not require any modification (attributes, etc), then the best solution that I can think if would be a custom DefaultContractResolver class. It would use reflection to determine if any IEnumerables for a given type are empty.

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题