使用System.Text.Json来忽略bool数据类型的默认值,只有

huangapple go评论68阅读模式
英文:

Using System.Text.Json to ignore default values for bool data type, only

问题

是否有一种在全局级别忽略所有布尔类型并在返回false时使用System.Text.Json的方法?

我知道有这个全局条件,但我仍然需要返回其他默认值。

JsonSerializerOptions options = new()
           {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
            };

理想情况下,不想单独对所有属性添加以下内容..
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]

英文:

Is there a way at a global level to ignore all and only bools when returning false with System.Text.Json?

I know there's this global condition, but I still need other default values to return.

JsonSerializerOptions options = new()
           {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault
            };

Ideally would not like to add the following to all propeties individually..
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]

答案1

得分: 2

以下是翻译好的部分:

无法为所有类型使用自定义 JsonConverter,因为那样你将不得不重新发明轮子来序列化整个对象。你也不能使用 JsonConverter<bool>(或 <bool?>),因为你必须在其 Write() 方法中编写一个值。

因此,要注册一个带有自定义 Modifiers 操作的 DefaultJsonTypeInfoResolver,仅在布尔值等于 true 时才进行序列化:

JsonSerializerOptions options = new()
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            jsonTypeInfo =>
            {
                foreach (var p in jsonTypeInfo.Properties)
                {
                    if (p.PropertyType == typeof(bool) || p.PropertyType == typeof(bool?))
                    {
                        p.ShouldSerialize = (containingObject, propertyValue) =>
                        {
                            return propertyValue as bool? == true;
                        };
                    }
                }
            }
        }
    }
};

来源自 MS Learn: Customize a JSON contract。适用于 .NET 7 以后的版本。

英文:

You can't use a custom JsonConverter for all types, because then you'll have to reinvent the wheel to serialize whole thing. You also can't use a JsonConverter&lt;bool&gt; (or &lt;bool?&gt;), because you have to write a value in its Write() method.

So register a DefaultJsonTypeInfoResolver with a custom Modifiers action that only serializes bools when their value equals true:

JsonSerializerOptions options = new()
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            jsonTypeInfo =&gt;
            {
                foreach (var p in jsonTypeInfo.Properties)
                {
                    if (p.PropertyType == typeof(bool) || p.PropertyType == typeof(bool?))
                    {
                        p.ShouldSerialize = (containingObject, propertyValue) =&gt;
                        {
                            return propertyValue as bool? == true;
                        };
                    }
                }
            }
        }
    }
};

From MS Learn: Customize a JSON contract. Works since .NET 7.

答案2

得分: 2

.NET 7及以后,你可以使用 typeInfo 修饰符 来定制你的类型的 合同,以跳过将值为 false 的 bool 属性进行序列化。

首先定义以下修饰符:

public static partial class JsonExtensions
{
    static Func<object, object?, bool> ShouldSerializeBool { get; } = static (obj, value) => (value is bool b ? b : true);

    public static Action<JsonTypeInfo> IgnoreFalseBoolProperties { get; } = static typeInfo => 
    {
        if (typeInfo.Kind != JsonTypeInfoKind.Object)
            return;
        foreach (var property in typeInfo.Properties)
            if (property.PropertyType == typeof(bool))
            {
                if (property.ShouldSerialize is {} shouldSerialize)
                    property.ShouldSerialize = (o, v) => ShouldSerializeBool(o, v) && shouldSerialize(o, v);
                else
                    property.ShouldSerialize = ShouldSerializeBool;
            }
    };
}

然后,如果你的模型看起来像这样,例如:

public record Model(bool BoolValue, int IntValue, bool? NullableBoolValue);

当你使用以下修改器对带有默认值的模型进行序列化时:

var options = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers = { JsonExtensions.IgnoreFalseBoolProperties },
    },
    // 其他如有需要
};
var json = JsonSerializer.Serialize(new Model(default, default, default), options);

bool 属性为 false 的部分将会被跳过:

{&quot;IntValue&quot;:0,&quot;NullableBoolValue&quot;:null}

但当带有 true bool 值进行序列化时:

var json2 = JsonSerializer.Serialize(new Model(true, default, default), options);

你将得到:

{&quot;BoolValue&quot;:true,&quot;IntValue&quot;:0,&quot;NullableBoolValue&quot;:null}

演示代码可以在 这里 查看。

英文:

In .NET 7 and later you can use a typeInfo modifier to customize your type's contract to skip serialization of bool properties whose value is false.

First define the following modifier:

public static partial class JsonExtensions
{
	static Func&lt;object, object?, bool&gt; ShouldSerializeBool { get; } = static (obj, value) =&gt; (value is bool b ? b : true);

	public static Action&lt;JsonTypeInfo&gt; IgnoreFalseBoolProperties { get; } = static typeInfo =&gt; 
		{
			if (typeInfo.Kind != JsonTypeInfoKind.Object)
				return;
			foreach (var property in typeInfo.Properties)
				if (property.PropertyType == typeof(bool))
				{
					if (property.ShouldSerialize is {} shouldSerialize)
						property.ShouldSerialize = (o, v) =&gt; ShouldSerializeBool(o, v) &amp;&amp; shouldSerialize(o, v);
					else
						property.ShouldSerialize = ShouldSerializeBool;
				}
		};
}

And now if your model looks like, e.g.:

public record Model(bool BoolValue, int IntValue, bool? NullableBoolValue);

When you serialize a model with default values using the modifier:

var options = new JsonSerializerOptions
{
	TypeInfoResolver = new DefaultJsonTypeInfoResolver
	{
		Modifiers = { JsonExtensions.IgnoreFalseBoolProperties },
	},
	// Others as required
};
var json = JsonSerializer.Serialize(new Model(default, default, default), options);

The false bool property will be skipped:

{&quot;IntValue&quot;:0,&quot;NullableBoolValue&quot;:null}

But when serialized with a true bool value:

var json2 = JsonSerializer.Serialize(new Model(true, default, default), options);

You will get:

{&quot;BoolValue&quot;:true,&quot;IntValue&quot;:0,&quot;NullableBoolValue&quot;:null}

Demo fiddle here.

huangapple
  • 本文由 发表于 2023年5月17日 23:15:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273639.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定