我正在使用json.net为winform应用程序实现memento pattern。我正在使用memento在失败的数据库事务上回滚对象。我得到的问题是,当反序列化纪念品时,调用getter而不是setter。让我演示一下:
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
扩展相同的基类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
和AnotherObjects
List
SomeObjects
getter,这会导致List从DB初始化,然后序列化列表将附加到它。让我在列表中的项目超出预期。但是,如果我删除延迟加载部分
public List<SomeObject> 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?
答案 0 :(得分:13)
Json.Net为此目的设置了ObjectCreationHandling
。尝试将其设置为Replace
,例如:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
MyObject obj = JsonConvert.DeserializeObject<MyObject>(memento, settings);