首页 > 解决方案 > 忽略列表中一种类型的序列化

问题描述

我正在使用JsonSerializer序列化/反序列化一个类,它运行良好。

但是在这个类中,有一个我想要序列化的列表,但不是针对列表中的每个元素。

此列表中有 3 种类型具有继承性:

FileInformationFolderInformation都继承自TreeViewElement

如何根据类型进行过滤?我想序列化所有 FolderInformations 实例,而不是 FileInformations。

标签: c#jsonserialization

解决方案


您可以使用JsonConverter列表属性上的属性在序列化期间过滤列表。

这是我在LINQPad中编写的示例:

void Main()
{
    var document = new Document
    {
        Id = 123,
        Properties = {
            new Property { Name = "Filename", Value = "Mydocument.txt" },
            new Property { Name = "Length", Value = "1024" },
            new Property {
                Name = "My secret property",
                Value = "<insert world domination plans here>",
                IsSerializable = false
            },
        }
    };

    var json = JsonConvert.SerializeObject(document, Formatting.Indented).Dump();
    var document2 = JsonConvert.DeserializeObject<Document>(json).Dump();
}

public class Document
{
    public int Id { get; set; }

    [JsonConverterAttribute(typeof(PropertyListConverter))]
    public List<Property> Properties { get; } = new List<Property>();
}

public class Property
{
    [JsonIgnore]
    public bool IsSerializable { get; set; } = true;
    public string Name { get; set; }
    public string Value { get; set; }
}

public class PropertyListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<Property>);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        var list = (existingValue as List<Property>) ?? new List<Property>(); 
        list.AddRange(serializer.Deserialize<List<Property>>(reader));
        return list;
    }

    public override void WriteJson(JsonWriter writer, object value,
        JsonSerializer serializer)
    {
        var list = (List<Property>)value;
        var filtered = list.Where(p => p.IsSerializable).ToList();
        serializer.Serialize(writer, filtered);
    }
}

输出:

{
  "Id": 123,
  "Properties": [
    {
      "Name": "Filename",
      "Value": "Mydocument.txt"
    },
    {
      "Name": "Length",
      "Value": "1024"
    }
  ]
}

您必须使您的属性适应您自己的类型和过滤条件,但这应该可以帮助您入门。


推荐阅读