问题描述
我有一个包含多个属性的对象,这些属性是字符串列表List<String>
或字符串字典Dictionary<string,string>
.我想使用 Json.net 将对象序列化为 json,并且希望生成最少的文本.
我正在使用 DefaultValueHandling 和 NullValueHandling 将默认值设置为字符串和整数.但是,如果将 DefaultValueHandling 初始化为空 List<String>
或 Dictionary<string,string>
,如何定义 DefaultValueHandling 以忽略序列化输出中的属性??p>
一些示例输出是:
{"Value1": "我的价值",价值2":3,列表1":[],列表2":[]}
我想得到一个忽略上例中两个列表的结果,因为它们被设置为空列表的默认值.
任何帮助将不胜感激
我已经在 自定义合约解析器(链接到特定提交,以防文件稍后移动).它使用一些辅助方法并包含一些用于自定义引用语法的无关代码.没有它们,代码将是:
公共类 SkipEmptyContractResolver : DefaultContractResolver{公共 SkipEmptyContractResolver (bool shareCache = false) : base(shareCache) { }受保护的覆盖 JsonProperty CreateProperty(MemberInfo 成员,MemberSerialization memberSerialization){JsonProperty 属性 = 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)) {谓词<宾语>newSerialize = obj =>{var collection = property.ValueProvider.GetValue(obj) as ICollection;返回集合 == null ||集合.计数!= 0;};谓词<宾语>oldShouldSerialize = 属性.ShouldSerialize;属性.ShouldSerialize = oldSerialize != null?o =>oldShouldSerialize(o) &&newShouldSerialize(o):新应序列化;}归还财产;}}
此合约解析器将跳过所有空集合的序列化(所有类型实现 ICollection
并具有 Length == 0
),除非 DefaultValueHandling.Include
为属性或字段指定.
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.
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>
?
Some sample output is:
{
"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.
Any help will be appreciated
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;
}
}
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 跳过空集合的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!