我有一个类定义如下的场景:
class MyObject { public DataDictionary MyObjectData { get; set; } public bool ShouldSerializeMyObjectData() { return true; } public bool ShouldDeserializeMyObjectData() { return false; } }
当我尝试使用JSON.net序列化/反序列化该类时,需要考虑ShouldSerialize,而不是ShouldDeserialize.
根据文档,两者都应该像我猜的那样工作.有什么特别值得我知道的吗?更一般地说,我应该如何处理我想要序列化属性但不反序列化它的场景?
如果重要的话,我正在使用Json.NET 8.0.
谢谢你的帮助.
解决方法
Json.NET在内部使用类JsonProperty
来定义如何将JSON属性映射到.NET成员或构造函数参数的协定.它有两个谓词属性,ShouldSerialize
和ShouldDeserialize
,当非空时,分别阻止属性被序列化和反序列化.初始化每个JsonProperty是ContractResolver
的工作.对于每个属性{PropertyName},Json.NET的default contract resolver会自动检查是否存在public bool ShouldSerialize{PropertyName}()
方法.如果存在这样的方法,它会在ShouldSerialize谓词中添加对它的调用,从而在方法返回false时抑制序列化.实现这是因为通过方法控制属性序列化ShouldSerialize {PropertyName}()是由例如XmlSerializer
支持的标准模式.有关更多背景,请参阅相关的Json.NET release notes.
例如,在以下类中,除非MyObjectData.Count>否则将禁止MyObjectData的序列化. 0:
class MyObject { public DataDictionary MyObjectData { get; set; } public bool ShouldSerializeMyObjectData() { return MyObjectData != null && MyObjectData.Count > 0; } }
但是,JsonProperty.ShouldDeserialize,它永远不会被默认的合约解析器设置.这可能是由于没有标准的反序列化模式等同于ShouldSerialize {PropertyName}(),因此Newtonsoft从未有过实现这种模式的请求.然而,正如您所注意到的,存在支持这种模式的基础设施,因此应用程序可以创建custom contract resolvers来实现这一目标.实际上,Json.NET在其自己的test suite中有一个这样的合同解析器的例子:
public class ShouldDeserializeContractResolver : DefaultContractResolver { public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver(); protected override JsonProperty CreateProperty(MemberInfo member,MemberSerialization memberSerialization) { JsonProperty property = base.CreateProperty(member,memberSerialization); MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name); if (shouldDeserializeMethodInfo != null) { property.ShouldDeserialize = o => { return (bool)shouldDeserializeMethodInfo.Invoke(o,null); }; } return property; } } public class ShouldDeserializeTestClass { [JsonExtensionData] public IDictionary<string,JToken> ExtensionData { get; set; } public bool HasName { get; set; } public string Name { get; set; } public bool ShouldDeserializeName() { return HasName; } }
如果要有条件地抑制属性的反序列化,即使存在于JSON中,也可以考虑使用(和caching)此合约解析程序.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。