You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# System.Text.Json如何仅对Optional<T>全局实现序列化忽略默认值

可行实现方案

方案1:使用JsonTypeInfoModifier全局配置Optional类型属性的忽略规则(推荐)

该方案可以全局给所有Optional<T>类型的属性自动添加默认值忽略规则,不会影响其他类型的序列化行为,也不需要手动给每个属性加特性,完全匹配你的需求。
实现代码如下:

using System.Text.Json;
using System.Text.Json.Serialization.Metadata;

public static class JsonSerializerOptionsExtensions
{
    public static void AddOptionalTypeIgnoreRule(this JsonSerializerOptions options)
    {
        options.TypeInfoResolverChain.Insert(0,
            JsonSerializerOptions.Default.TypeInfoResolver!.WithAddedModifier(typeInfo =>
            {
                // 遍历所有待序列化的属性
                foreach (var property in typeInfo.Properties)
                {
                    // 筛选出类型为Optional<T>的属性
                    var propertyType = property.PropertyType;
                    if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Optional<>))
                    {
                        // 给该属性单独设置默认值忽略规则
                        property.JsonIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault;
                    }
                }
            }));
    }
}

使用时仅需在你的序列化配置中调用扩展方法即可:

var options = new JsonSerializerOptions();
options.AddOptionalTypeIgnoreRule();
// 后续正常使用options执行序列化即可

该方案无侵入性,不会修改其他类型的序列化逻辑,只有Optional<T>类型的属性会在值为默认(即HasValue = false)时被自动忽略序列化。


方案2:自定义Optional全局JsonConverter

如果你同时需要自定义Optional<T>的序列化输出格式,可以选择自定义转换器的实现方式:

public class OptionalJsonConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(Optional<>);
    }

    public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        var valueType = typeToConvert.GetGenericArguments()[0];
        var converterType = typeof(OptionalJsonConverter<>).MakeGenericType(valueType);
        return (JsonConverter?)Activator.CreateInstance(converterType);
    }

    private class OptionalJsonConverter<T> : JsonConverter<Optional<T>>
    {
        public override Optional<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            var value = JsonSerializer.Deserialize<T>(ref reader, options);
            return new Optional<T>(value!);
        }

        public override void Write(Utf8JsonWriter writer, Optional<T> value, JsonSerializerOptions options)
        {
            if (value.HasValue)
            {
                JsonSerializer.Serialize(writer, value.Value, options);
            }
            else
            {
                writer.WriteNullValue();
            }
        }
    }
}

使用时将转换器工厂添加到序列化配置中:

var options = new JsonSerializerOptions
{
    // 配合忽略null值规则实现Optional默认值忽略,不会影响其他值类型
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
options.Converters.Add(new OptionalJsonConverterFactory());

注意事项

两种方案均要求.NET 6及以上版本运行环境,方案1适配性更高,不需要修改全局的默认忽略规则,更建议优先使用。

内容的提问来源于stack exchange,提问作者Kaffu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 00:18:03