我正在使用JSON.NET将类序列化为JSON。该类包含一个由项列表组成的属性,我想以自定义方式自行序列化项(通过使用自定义的ContractResolver动态地仅包含某些属性)。所以基本上我想用标准方式使用DefaultContractResolver序列化父类本身,但是使用我自己的ContractResolver以自定义方式序列化这一个属性。
JSON.NET有可能允许这样的方法,但文档相当粗略。任何帮助将不胜感激。
答案 0 :(得分:2)
我用ContractResolver解决了这个问题。我要序列化的对象列表是异构的,因此我必须传递两个参数,一个要序列化的属性列表,以及一个应用属性列表的类型列表。所以它看起来像这样:
public class DynamicContractResolver : DefaultContractResolver
{
private List<string> mPropertiesToSerialize = null;
private List<string> mItemTypeNames = new List<string>();
public DynamicContractResolver( List<string> propertiesToSerialize,
List<string> itemTypeNames )
{
this.mPropertiesToSerialize = propertiesToSerialize;
this.mItemTypeNames = itemTypeNames;
}
protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
{
IList<JsonProperty> properties = base.CreateProperties( type, memberSerialization );
if( this.mItemTypeNames.Contains( type.Name ) )
properties = properties.Where( p => mPropertiesToSerialize.Contains( p.PropertyName ) ).ToList();
return properties;
}
}
它被称为:
DynamicContractResolver contractResolver = new DynamicContractResolver( propsToSerialize, GetItemTypeNames() );
json = JsonConvert.SerializeObject( this, Formatting.None,
new JsonSerializerSettings { ContractResolver = contractResolver } );
其中GetItemTypeNames()调用GetType()。列表中我想序列化的每个项的名称,并将它们明确地写入列表。
抱歉,我原来的问题含糊不清,措辞严厉,如果有人有更好的解决方案,我当然不会坚持这个问题。
答案 1 :(得分:0)
这是一个更好的版本。它将类型名称与属性相关联,因此您可以指定希望在每个级别上序列化的属性。字典的键是类型名。该值是每种类型要序列化的属性的列表。
class PropertyContractResolver : DefaultContractResolver
{
public PropertyContractResolver( Dictionary<string, IEnumerable<string>> propsByType )
{
PropertiesByType = propsByType;
}
protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
{
IList<JsonProperty> properties = base.CreateProperties( type, memberSerialization );
if( this.PropertiesByType.ContainsKey( type.Name ) )
{
IEnumerable<string> propsToSerialize = this.PropertiesByType[ type.Name ];
properties = properties.Where( p => propsToSerialize.Contains( p.PropertyName ) ).ToList();
}
return properties;
}
private Dictionary<string, IEnumerable<string>> PropertiesByType
{
get;
set;
}
}