Clear collections before adding items when populating existing objects(在填充现有对象时添加项目之前清除集合)
问题描述
我有一个对象,它有几个用公共 getter 但私有 setter 定义的集合属性,在这种情况下,JsonConvert.PopulateObject
将反序列化的项目添加到这些集合中,而现有项目保持不变.
I have an object which has several collection properties defined with public getter but private setter, In this case JsonConvert.PopulateObject
adds the deserialized items to these collections leaving the existing items untouched.
当此类成员集合在反序列化之前被清除时,我需要一种行为.
I need a behavior when such member collections get cleared before deserialization.
我尝试在标有 [OnDeserializing]
属性的方法中手动清除集合.
I tried to manually clear the collections in a method marked with the [OnDeserializing]
attribute.
这种方法的问题在于,即使 JSON 字符串中不存在集合属性,它仍然会清除集合.
The problem with that approach is that it will still clear the collections even if the collection property does not exist in the JSON string.
当只有那些在 JSON 字符串中实际定义的集合被清除时,我需要一种方法.那些未定义的应该保持不变.
I need a way when only those collections get cleared which are actually defined in the JSON string. Those which are undefined should be kept untouched.
谢谢
推荐答案
好的,经过一番访问 Json.NET 资源后,我通过从 DefaultContractResolver
继承自定义合约解析器找到了以下解决方案.
Okay, so after some trip to Json.NET sources I found the following solution by inheriting a custom contract resolver from DefaultContractResolver
.
我需要重写数组合约创建以添加反序列化回调.此时回调接收到具体的集合实例,因此我们可以对其进行操作(在这种情况下清除它).
I needed to override the array contract creation to add a deserialization callback. At this point the callback receives the concrete collection instance, so we can manipulate it (in this case clear it).
只要我能确定,使用它是安全的,但请随时警告这种方法的任何缺点.
As long as I can determine, it is safe to use, but feel free to warn about any drawbacks of this method.
注意:我是唯一认为这应该是默认行为的人吗?
public class CollectionClearingContractResolver : DefaultContractResolver
{
protected override JsonArrayContract CreateArrayContract(Type objectType)
{
var c = base.CreateArrayContract(objectType);
c.OnDeserializingCallbacks.Add((obj, streamingContext) =>
{
var list = obj as IList;
if (list != null && !list.IsReadOnly)
list.Clear();
});
return c;
}
}
...
public class Test {
public List<int> List { get; private set; }
public Test() {
List = new List<int>();
}
}
...
var myObj = new Test();
myObj.List.AddRange(new[] {1,2,3});
var listReference = myObj.List;
JsonConvert.PopulateObject("{ List: [4, 5, 6] }", myObj,
new JsonSerializerSettings {
ContractResolver = new CollectionClearingContractResolver(),
});
myObj.List.ShouldEqual(listReference); // didn't recreate list
myObj.List.Count.ShouldEqual(3);
myObj.List.SequenceEqual(new[] { 4, 5, 6}).ShouldBeTrue();
这篇关于在填充现有对象时添加项目之前清除集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在填充现有对象时添加项目之前清除集合
基础教程推荐
- c# Math.Sqrt 实现 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 如何激活MC67中的红灯 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01