澄清(对于处于相同情况的任何人):
请注意,我的任务是序列化现有的旧对象。因此,我宁愿调整序列化程序而不是干扰数据结构。
我相信在大多数情况下,最好直接从数据中删除重复项,如@ danny-chen的enter image description here所示。
作为我想要使用JSON.Net序列化的对象的一部分,有一个string[] files
属性包含重复项:
some/path/to/f1.jpg
some/path/to/f1.jpg
some/path/to/f2.jpg
some/path/to/f3.jpg
some/path/to/f2.jpg
让我们假设这些不一定是有序的(f2, f3, f2
)。
是否可以序列化数组并忽略重复项?预期结果:
{
"files": [
"some/path/to/f1.jpg",
"some/path/to/f2.jpg",
"some/path/to/f3.jpg"
]
}
我尝试了PreserveReferencesHandling
设置,但由于数组中的每个file
都是一个不同的对象,可能会重复,因此无效。
答案 0 :(得分:5)
它不是序列化的一部分,它是数据处理的一部分。我建议您在序列化之前删除重复项。
string[] files = GetFiles();
data.Files = files.Distinct().ToArray();
//serialize data
//instead of data.Files = files; and do tricky things in serialization
答案 1 :(得分:2)
最简单的解决方案是按照@Danny Chen的建议在序列化之前过滤列表。但是,如果您在序列化期间必须这样做,则可以使用自定义JsonConverter
。
以下是您需要的代码:
public class RemoveDuplicatesConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IEnumerable<T>).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartArray();
foreach (T item in ((IEnumerable<T>)value).Distinct())
{
serializer.Serialize(writer, item);
}
writer.WriteEndArray();
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用转换器,请在类中的列表或数组属性中添加[JsonConverter]
属性,以便删除重复项,如下所示。确保转换器的通用类型与列表类型匹配。
class Foo
{
[JsonProperty("files")]
[JsonConverter(typeof(RemoveDuplicatesConverter<string>))]
public string[] Files { get; set; }
}
然后正常序列化。 JSON中的列表将删除重复项,但对象中的原始列表将不受影响。
string json = JsonConvert.SerializeObject(your_object, Formatting.Indented);