忽略列表中一种类型的序列化

时间:2019-07-08 13:20:22

标签: c# json serialization

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

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

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

分别从 TreeViewElement 继承的

FileInformation FolderInformation

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

2 个答案:

答案 0 :(得分:2)

您可以在列表属性上使用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"
    }
  ]
}

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

答案 1 :(得分:0)

您可以使用[JsonIgnore] Attribute来忽略整个属性

赞:

class Cls
{
    public string prop1 { get; set; }

    public string prop2 { get; set; }

    [JsonIgnore]
    public string prop3 { get; set; }

}

class Program
{

    static void Main(string[] args)
    {
        var cls = new Cls
        {
            prop1 = "lorem",
            prop2 = "ipsum",
            prop3 = "dolor"            
        };

        System.Console.WriteLine(JsonConvert.SerializeObject(cls));
        //Output: {"prop1":"lorem","prop2":"ipsum"}
    }
}

编辑:仅忽略该值。

如果仅是值,则需要忽略而不是整个属性:

class Cls
{
    public List<string> prop1 { get; set; }

    public List<string> prop2 { get; set; }

    public List<string> prop3 { get; set; }

    [OnSerializing()]
    internal void OnSerializingMethod(StreamingContext context)
    {
        prop3 = null;
    }

}

class Program
{

    static void Main(string[] args)
    {
        var cls = new Cls
        {
            prop1 =  new List<string>{ "lorem", "ipsum", "dolor" },
            prop2 =  new List<string>{ "lorem", "ipsum", "dolor" },
            prop3 =  new List<string>{ "lorem", "ipsum", "dolor" },
        };

        System.Console.WriteLine(JsonConvert.SerializeObject(cls)); //Output: {"prop1":["lorem"],"prop2":["lorem"],"prop3":null}
    }
}