Json.Net在列表反序列化期间调用属性getter,导致重复项
我正在使用json.net来实现winform应用程序的memento模式 。 我正在使用memento在失败的数据库事务上回滚对象。 我得到的问题是,当反序列化纪念品时,调用getter而不是setter。 让我来certificate一下:
class MyClass { public int ID { get; set; } public string field1 { get; set; } public string field2 { get; set; } private List _someObjects; public List SomeObjects { get { if(_someObjects == null) { _someObjects = LoadSomeObjectsFromDB(); } return _someObjects; } set { _someObjects = value; } } private List _anotherObjects; public List AnotherObjects { get { if(_anotherObjects == null) { _anotherObjects= LoadAnotherObjectsFromDB(); } return _anotherObjects ; } set { _anotherObjects = value; } } }
* MyObject
, SomeObject
和SomeObject
扩展了相同的基类Model
从上面的示例类中可以看出,如果尚未加载SomeObjects,它将使用Lazy Loading从数据库加载它。 现在当我序列化这个对象时。
string memento = JsonConvert.SerializeObject(obj);
导致
{ "ID": 1, "field1": "field 1", "field2": "field 2", "SomeObjects": [ { "ID": 1, }, { "ID": 2, }, { "ID": 3, } ], "AnotherObjects": [ { "ID": 4, }, { "ID": 5, }, { "ID": 6, } ] }
然后反序列化它。
MyObject obj = JsonConvert.DeserializeObject(memento, typeof(MyObject));
我得到一个由以下JSON表示的对象
{ "ID": 1, "field1": "field 1", "field2": "field 2", "SomeObjects": [ { "ID": 1, }, { "ID": 2, }, { "ID": 3, }, { "ID": 1, }, { "ID": 2, }, { "ID": 3, } ], "AnotherObjects": [ { "ID": 4, }, { "ID": 5, }, { "ID": 6, }, { "ID": 4, }, { "ID": 5, }, { "ID": 6, } ] }
SomeObjects
和SomeObjects
List
的项太多
SomeObjects
getter,这会导致List从DB初始化,然后序列化列表将附加到它。 让我在列表中的项目多于预期。 但是如果我删除了Lazy Loading部分
public List SomeObjects { get { /*if(_someObjects == null) { _someObjects = LoadSomeObjectsFromDB(); }*/ return _someObjects; } set { _someObjects = value; } }
仍然会调用getter,但返回null。 然后json.net调用setter,其value
一个列表,其中已经添加了正确数量的元素,而如果getter返回一个初始化的列表,它会追加到它永远不会调用setter。 为什么差异,如果列表已经初始化,则调用getter并附加到。 但是如果没有初始化,则会调用setter并使用已填充对象的列表对其进行初始化。 有没有办法让json.net在反序列化通用List
期间只调用setter?
为此,Json.Net有一个ObjectCreationHandling
设置。 尝试将其设置为Replace
,例如:
JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ObjectCreationHandling = ObjectCreationHandling.Replace; MyObject obj = JsonConvert.DeserializeObject(memento, settings);
演示: https : //dotnetfiddle.net/rkY1pt
- 条件DataGridView格式
- 在InitializeComponent期间WPF获取控件空引用
- 用逗号(,)转换c#decimal toString()
- Dispatcher Invoke(…)vs BeginInvoke(…)混淆
- DataGridView和List 的DataBinding与BindingSource
- 从Windows窗体访问asmx服务会产生最大请求长度错误
- 错误索引方法’Class.Method’无法将参数’log’绑定到类型TraceWriter
- MYSQL中不存在规范函数“EntityFunctions.TruncateTime”
- 使用.NET 4.5解压缩受密码保护的ZIP文件