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
相关产品推荐
相关产品推荐

