问题描述
我使用json.net实施。我使用的是纪念回滚上失败的数据库事务的对象。我得到的问题是,反序列化时的纪念品,吸气剂被称为而非制定者。让我来演示:
I'm using json.net to implement the memento pattern for a winform application. I'm using the memento to rollback an object on a failed database transaction. The problem I'm getting is that when deserializing the memento, the getter is called rather than the setter. Let me demonstrate:
class MyClass
{
public int ID { get; set; }
public string field1 { get; set; }
public string field2 { get; set; }
private List<SomeObject> _someObjects;
public List<SomeObject> SomeObjects
{
get
{
if(_someObjects == null)
{
_someObjects = LoadSomeObjectsFromDB();
}
return _someObjects;
}
set
{
_someObjects = value;
}
}
private List<AnotherObject> _anotherObjects;
public List<AnotherObject> AnotherObjects
{
get
{
if(_anotherObjects == null)
{
_anotherObjects= LoadAnotherObjectsFromDB();
}
return _anotherObjects ;
}
set
{
_anotherObjects = value;
}
}
}
* 为MyObject
, SomeObject
和 AnotherObject
延长相同的基类,模式
*MyObject
, SomeObject
, and AnotherObject
extend the same base class, Model
你可以从样本类上面看,如果SomeObjects尚未加载,它使用的从数据库加载它。现在当我序列化这个对象
As you can see from the sample class above, if SomeObjects is not loaded yet, it uses Lazy Loading to load it from the Database. Now When I serialize this object.
string memento = JsonConvert.SerializeObject(obj);
致使
Resulting in
{
"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
I get an object represented by the following 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
和 AnotherObjects
<$ C $项目过多C>列表取值
SomeObjects
调用getter时,这会导致列表进行初始化从DB则系列化列表追加到它。留下我在比预期列表中更多的项目。但是,如果我删除延迟加载部分
SomeObjects
getter is called, which causes the List to initialize from the DB then the serialized list is Appended to it. Leaving me with more items in the list than desired. But if I remove the Lazy Loading portion
public List<SomeObject> SomeObjects
{
get
{
/*if(_someObjects == null)
{
_someObjects = LoadSomeObjectsFromDB();
}*/
return _someObjects;
}
set
{
_someObjects = value;
}
}
吸气剂仍称,但返回null。然后调用json.net与二传值
要与已经加入,正确数量的元素列表而如果吸气返回一个列表initalized,其追加到它永远不会调用的部份二传手。为什么差异,如果列表已经初始化,调用getter时,它是附加到。但如果没有进行初始化,设定器被调用,它与已填充有对象的列表进行初始化。有没有一种方法,使json.net只有一个通用的列表
?
The getter is still called, but returns null. Then json.net calls the setter with value
being a list with the correct number of elements already added, whereas if the getter returns an initalized list, it appends to it never calling ths setter. Why the discrepancy, if a list is already initialized, the getter is called and it is appended to. But if not initialized, the setter is called and it is initialized with a list already filled with objects. Is there a way to make json.net only call the setter during deserialization of a generic List
?
推荐答案
Json.Net有一个设置用于这一目的。尝试将它设置为替换
,例如:
Json.Net has an ObjectCreationHandling
setting for this purpose. Try setting it to Replace
, e.g.:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
MyObject obj = JsonConvert.DeserializeObject<MyObject>(memento, settings);
演示:
这篇关于Json.Net列表的反序列化期间调用属性getter,造成重复项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!