我想仅序列化已更改的属性。我设法为root类型执行此操作,但它包含对要序列化的其他对象的引用(甚至可能是相同的类型)。
这是我的界面和ContractResolver:
public interface ISelectiveJsonSerialize
{
IList<string> PropertiesToSerialize { get; }
}
public class JsonSelectiveSerializeContractResolver : DefaultContractResolver
{
private readonly IList<string> _propertiesToSerialize;
public JsonSelectiveSerializeContractResolver(IList<string> propertiesToSerialize)
{
_propertiesToSerialize = propertiesToSerialize;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, memberSerialization).Where(p => _propertiesToSerialize.Contains(p.PropertyName)).ToList();
}
}
属性PropertiesToSerialize将包含一个接收值的属性名称列表。
这是我序列化的方式:
string result = "";
if (val is ISelectiveJsonSerialize)
{
// Don't serialize all properties
var resolver = new JsonSelectiveSerializeContractResolver(((ISelectiveJsonSerialize)val).PropertiesToSerialize);
var settings = new JsonSerializerSettings { ContractResolver = resolver };
result = JsonConvert.SerializeObject(val, Formatting.None, settings);
}
else
{
// Default serialization
result = JsonConvert.SerializeObject(val);
}
return result;
这是我可以序列化的类型的示例:
public class Category : BaseType
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
PropertiesToSerialize.Add("Name");
}
}
private Category _category;
public Category Category
{
get { return _category; }
set
{
_category = value;
PropertiesToSerialize.Add("Category");
}
}
}
正如您所理解的,如果我只为我的根类型设置了一个具有名称的类别,它将不会序列化该名称,因为根PropertiesToSerialize不包含“Name”,如果它将序列化根实体的空名称。
帮助?
答案 0 :(得分:1)
您可以使用Json.NET的conditional property serialization功能来添加测试,以确定在序列化之前是否修改了给定属性:
public class JsonSelectiveSerializeContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
var shouldSerialize = property.ShouldSerialize;
var name = property.PropertyName;
property.ShouldSerialize = (o) =>
{
var selectiveSerialize = o as ISelectiveJsonSerialize;
if (selectiveSerialize != null)
{
if (!selectiveSerialize.PropertiesToSerialize.Contains(name))
return false;
}
return shouldSerialize == null || shouldSerialize(o);
};
return property;
}
}
示例fiddle。