System.Text.Json условно игнорирует свойство во время выполнения

#c# #system.text.json

#c# #system.text.json

Вопрос:

Интересно, есть ли способ игнорировать свойство во время выполнения?

например, у меня есть такой класс, как этот

 public class FooBar
{
   public string Foo { get; set; }
   public string Bar { get; set; }
}
 

Я хочу условно игнорировать свойство Bar во время выполнения. таким образом, свойство не может быть сериализовано в моем json.

Прямо сейчас я использую NET 5.0.

Заранее спасибо

Комментарии:

1. Что именно подразумевает слово «условно» в этом вопросе? Вы хотите сериализовать его или нет, основываясь на каком-то условии? Или, возможно, вы хотите условно игнорировать его?

2. @LasseV.Karlsen я хочу сериализовать его на основе некоторого условия

3. @JohnSari Затем вы можете создать анонимный объект (вариант 1) в моем ответе. Проверьте условие. Если выполнено, то создайте анонимный объект. If (condition) { anonymous object with custom properties } else { serialize C# object will all properties } .

Ответ №1:

Я бы использовал пользовательский конвертер json:

 public class FooBarConverter : JsonConverter<FooBar>
{
    public override FooBar Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var fooBar = new FooBar();
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
            {
                return fooBar;
            }

            if (reader.TokenType == JsonTokenType.PropertyName)
            {
                var propertyName = reader.GetString();
                reader.Read();
                switch (propertyName)
                {
                    case nameof(FooBar.Bar):
                        var bar = reader.GetString();
                        fooBar.Bar = bar;
                        break;
                    case nameof(FooBar.Foo):
                        var foo = reader.GetString();
                        fooBar.Foo = foo;
                        break;
                }
            }
        }
        throw new JsonException();
    }

    public override void Write(Utf8JsonWriter writer, FooBar value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();

        writer.WriteString(nameof(FooBar.Bar), value.Bar);
        // your condition
        writer.WriteString(nameof(FooBar.Foo), value.Foo);

        writer.WriteEndObject();
    }
}
 

Как использовать пользовательский конвертер.

 var serializerOptions = new JsonSerializerOptions
{
    Converters = { new FooBarConverter() }
};

var fooBar = new FooBar { Bar = "bar", Foo = "foo" };
var json = JsonSerializer.Serialize(fooBar, serializerOptions);
var deserializedFooBar = JsonSerializer.Deserialize<FooBar>(json, serializerOptions);
 

В Write методе вы можете указать свое условие и на основе условия вызвать write.WriteString его .

Если условие основано на значении другого объекта, то вы можете передать объект перед сериализацией / десериализацией. Я думаю, что в некоторых случаях это может быть недостатком.

Комментарии:

1. msdn: docs.microsoft.com/en-us/dotnet/standard/serialization/…

2. @FLYFLU использование упрощается, поскольку весь контекст неизвестен.

3. Итак, мне все еще нужно вручную перебирать все свойства .Write вручную

Ответ №2:

У вас есть несколько доступных вариантов :

Вариант 1: вместо этого вы можете создавать анонимные объекты на C# :

 FooBar obj = new FooBar();
var anon = new {
    Foo = obj.Foo;
};
 

Вариант 2: вы можете использовать JsonIgnore :

 public class FooBar
{
   public string Foo { get; set; }
   [JsonIgnore]
   public string Bar { get; set; }
}
 

В общем, первый вариант даст вам больше гибкости. В вашем конкретном случае, поскольку вы условно хотите игнорировать свойства, будет выбран вариант 1. Вы можете записать свое условие как :

 If (condition)
{
   var anon = new
   {
      Foo = obj.Foo;
   };
}
else
{
    var notAnon = JsonConvert.SerializeObject(obj);  //Serialize with all the properties in it
    //OR do something else
}