How to omit empty collections when serializing with Json.NET

帅比萌擦擦* 提交于 2019-12-09 02:29:42

问题


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<string> Y = new List<string>();
}

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

The value of json here is

{ "Y": [] }

but I would like it to be { } if Y is an empty list.

I couldn't find a satisfactory way to achieve this. Maybe with a custom contract resolver?


回答1:


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



回答2:


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.



来源:https://stackoverflow.com/questions/34903151/how-to-omit-empty-collections-when-serializing-with-json-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!