C# System.Text.Json在运行时有条件地忽略属性

C# 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中序列化 我现在正在使用NET5.0 提前感谢您有两种选择: 选项1:您可以改为在C#中创建匿名对象: 选项2:您可以使用JsonIgnore: public class FooB

我想知道,是否有一种方法可以忽略运行时的属性

例如,我有这样的课

public class FooBar
{
   public string Foo { get; set; }
   public string Bar { get; set; }
}
我想在运行时有条件地忽略属性
Bar
。因此,属性不能在我的json中序列化

我现在正在使用NET5.0


提前感谢

您有两种选择:

选项1:您可以改为在C#中创建匿名对象:

选项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
}

我将使用自定义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();
    }
}
公共类FooBarConverter:JsonConverter
{
公共覆盖FooBar Read(参考Utf8JsonReader reader,键入typeToConvert,JsonSerializerOptions选项)
{
var fooBar=新fooBar();
while(reader.Read())
{
if(reader.TokenType==JsonTokenType.EndObject)
{
返回fooBar;
}
if(reader.TokenType==JsonTokenType.PropertyName)
{
var propertyName=reader.GetString();
reader.Read();
交换机(propertyName)
{
案例名称(FooBar.Bar):
var bar=reader.GetString();
fooBar.Bar=Bar;
打破
案例名称(FooBar.Foo):
var foo=reader.GetString();
fooBar.Foo=Foo;
打破
}
}
}
抛出新的JsonException();
}
公共重写无效写入(Utf8JsonWriter写入程序、FooBar值、JsonSerializerOptions选项)
{
writer.WriteStartObject();
writer.WriteString(nameof(FooBar.Bar)、value.Bar);
//你的情况
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);
var serializerOptions=新的JsonSerializerOptions
{
转换器={new FooBarConverter()}
};
var fooBar=newfoobar{Bar=“Bar”,Foo=“Foo”};
var json=JsonSerializer.Serialize(fooBar,serializerOptions);
var deserializedFooBar=JsonSerializer.Deserialize(json,serializerOptions);
Write
方法中,您可以指定您的条件,并根据条件调用
Write.WriteString

如果条件基于另一个对象的值,则可以在序列化/反序列化之前传递该对象。我认为这在某些情况下可能是不利的。

在这个问题中,“有条件地”一词到底意味着什么?是否要根据某些条件序列化它?或者你想无条件地忽略它吗?@LasseV.Karlsen我想根据一些condition@JohnSari然后您可以在我的答案中创建一个匿名对象(选项1)。检查情况。如果满足,则创建匿名对象
If(condition){anonymous object with custom properties}else{serialize C#object will all properties}
.msdn:@FLYFLU由于不知道整个上下文,因此简化了用法。
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);