我使用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
。
我无法找到满意的方法来实现这一目标。也许有自定义合同解析器?
答案 0 :(得分:14)
如果您正在寻找可以在不同类型中使用的解决方案,并且不需要任何修改(属性等),那么我认为最好的解决方案是自定义DefaultContractResolver
类。它将使用反射来确定给定类型的任何IEnumerable
是否为空。
public class IgnoreEmptyEnumerablesResolver : DefaultContractResolver
{
public new 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;
}
}
答案 1 :(得分:0)
如果您可以修改类,可以添加Shrink方法并为所有空集合设置null。它需要更改类,但它具有更好的性能。只是另一种选择。