У меня урок

public class SettingsExpires : ViewModelBase
{
    private int? frequency;
    [JsonProperty("frequency")]
    public int? Frequency
    {
        get => frequency;
        set => this.Set(ref frequency, value);
    }
}

Где ViewModelBase — класс abstract из GalaSoft.MvvmLight. Моя проблема начинается, когда я пытаюсь сериализовать свой класс в json и получаю следующее:

{{  "frequency": null, "IsInDesignMode": false}}

Я получаю IsInDesignMode из базового класса ViewModelBase

public bool IsInDesignMode { get; }

Как я могу игнорировать это свойство из базового класса? Я пробовал что-то вроде этого:

public class SettingsExpires : ViewModelBase
{
    private int? frequency;
    [JsonProperty("frequency")]
    public int? Frequency
    {
        get => frequency;
        set => this.Set(ref frequency, value);
    }
    [JsonIgnore]
    public new bool IsInDesignMode { get; }
}

Или это:

public class SettingsExpires : ViewModelBase
{
    private int? frequency;
    [JsonProperty("frequency")]
    public int? Frequency
    {
        get => frequency;
        set => this.Set(ref frequency, value);
    }
    [JsonIgnore]
    public bool IsInDesignMode { get; }
}

Но это не работает

1
Янислав Колодочка 19 Янв 2022 в 16:30
1
Вы пытались украсить свой класс SettingsExpires с помощью [JsonObject(MemberSerialization.OptIn)]?
 – 
Peter Csala
19 Янв 2022 в 16:46
1
Оно работает. Благодарить
 – 
Янислав Колодочка
19 Янв 2022 в 17:02

3 ответа

Лучший ответ

Украсив свой производный класс (SettingsExpires) следующим атрибутом:

[JsonObject(MemberSerialization.OptIn)]

Вы в основном указываете сериализатору включать только те свойства, которые явно аннотированы JsonProperty. Все остальное будет игнорироваться.

Справка

0
Peter Csala 19 Янв 2022 в 17:05
1
Похоже, у нас была такая же идея :)
 – 
AFract
19 Янв 2022 в 17:08

Вы можете определить собственный сопоставитель контрактов, чтобы игнорировать свойства. Например,

public class ShouldSerializeContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);

        if (property.DeclaringType == typeof(ViewModelBase) && property.PropertyName == "IsInDesignMode")
        {
            property.ShouldSerialize = x=> false;
        }

        return property;
    }
}

Теперь вы можете сериализовать свои данные, указав преобразователь контракта.

var result = JsonConvert.SerializeObject(
    data,
    Formatting.Indented,
    new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver() }
);
1
Anu Viswan 19 Янв 2022 в 16:53

Ану Висван дал (ИМХО) очень хорошее решение.

В качестве альтернативы вы можете использовать атрибут [JsonObject(MemberSerialization.OptIn)] поверх ваших классов для сериализации, что даст вам возможность четко выбирать, какие поля вы хотите сериализовать.

Но у него есть недостаток: вам придется поместить [JsonProperty] для каждого свойства, которое вы хотите в JSON. В некоторых случаях это очень полезно, но может быть утомительно, если вам нужно сериализовать много классов.

Вы можете выбрать, какое решение выглядит лучшим для вас :)

0
AFract 19 Янв 2022 в 17:04
1
Может ли человек, который проголосовал за мой ответ, объяснить, почему? Кажется, это хорошее решение, и я объяснил, почему иногда это не так.
 – 
AFract
19 Янв 2022 в 17:08