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; } } } 

* MyObjectSomeObjectSomeObject扩展了相同的基类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, } ] } 

SomeObjectsSomeObjects 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