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

为何自定义System.Text.Json.DateTime转换器会触发可空DateTime属性读取?

问题根因

System.Text.Json 对可空值类型(Nullable<T>/T?)有内置适配逻辑:当处理T?类型的属性时,只要属性值不为null,序列化器会自动剥离Nullable<>的外层包装,使用对应非可空类型T的匹配转换器处理实际值,这就是你仅适配了DateTime的转换器会被DateTime?属性触发执行的原因。你观察到的第5次CanConvert调用,就是序列化器处理DateTime?属性内部非空值时发起的类型检测。

当JSON里Expired字段传null时,序列化器会直接给属性赋值null,不会触发你的转换器逻辑,你不需要担心可空场景下的null返回问题。

修复方案

方案1:优化现有转换器逻辑(推荐,无需新增代码)

你现有转换器的Read方法只需要优化异常处理逻辑即可,不需要单独适配可空场景:

public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
    if (reader.TryGetDateTime(out var date))
    {
        return date;
    }
    // 可替换为业务需要的自定义异常类型
    throw new JsonException("无效的日期时间格式");
}

方案2:新增可空DateTime专属转换器(适用于有特殊处理需求的场景)

如果你对DateTime?类型有单独的处理逻辑,可以额外实现对应转换器,注册后序列化器会优先匹配精准类型的转换器:

public class UserBasedNullableDateTimeJsonConverter : JsonConverter<DateTime?>
{
    private readonly UserBasedDateTimeJsonConverter _innerConverter;
    
    public UserBasedNullableDateTimeJsonConverter(IHttpContextAccessor httpContextAccessor)
    {
        _innerConverter = new UserBasedDateTimeJsonConverter(httpContextAccessor);
    }

    public override bool CanConvert(Type typeToConvert)
    {
        return typeof(DateTime?) == typeToConvert;
    }

    public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Null)
        {
            return null;
        }
        return _innerConverter.Read(ref reader, typeof(DateTime), options);
    }

    public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
    {
        if (value == null)
        {
            writer.WriteNullValue();
            return;
        }
        _innerConverter.Write(writer, value.Value, options);
    }
}

随后在CustomJsonOptions的Configure方法中注册该转换器即可:

public void Configure(JsonOptions options)
{
    options.JsonSerializerOptions.Converters.Add(new UserBasedDateTimeJsonConverter(_accessor));
    options.JsonSerializerOptions.Converters.Add(new UserBasedNullableDateTimeJsonConverter(_accessor));
}

额外提示:你现有代码里CustomJsonOptions的构造方法名称写为了FeatureConfigJsonOptions,和类名不一致属于笔误,会触发编译错误,记得修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:57:02