Игнорировать сериализацию для одного типа в списке - PullRequest
1 голос
/ 08 июля 2019

Я использую JsonSerializer для сериализации / десериализации класса, и он работает хорошо.

Но в этом классе есть список, который я хочу сериализовать, но не для всех элементов в списке.

В этом списке 3 типа с наследованием:

FileInformation и FolderInformation , которые оба наследуются от TreeViewElement .

Как я могу фильтровать в зависимости от типа?Я хочу сериализовать все экземпляры FolderInformations, но не FileInformations.

Ответы [ 2 ]

2 голосов
/ 08 июля 2019

Вы можете использовать атрибут 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"
    }
  ]
}

Вы должны адаптировать свой атрибут к вашим собственным типам и критериям фильтрации, но это должно помочь вам начать.

0 голосов
/ 08 июля 2019

Вы можете использовать атрибут [JsonIgnore] , чтобы игнорировать все свойство

Примерно так:

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}
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...