System.Text.Json.Serialization.JsonConverter<DateTime> 也针对可为 null 的 DateTime 属性执行

System.Text.Json.Serialization.JsonConverter<DateTime> is executed for nullable DateTime properties as well

所以,基本上我想创建一个自定义转换器,以便根据用户时区转换日期时间值。这是代码:

public class UserBasedDateTimeJsonConverter : System.Text.Json.Serialization.JsonConverter<DateTime>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public UserBasedDateTimeJsonConverter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

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

    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TryGetDateTime(out var date))
        {
            return date;
        }

        throw new Exception("Error");
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        if (_httpContextAccessor.HttpContext is not null)
        {
            var securityContextProvider = _httpContextAccessor.HttpContext.RequestServices.GetRequiredService<ISecurityContextProvider>();

            var securityContext = securityContextProvider.SecurityContext;

            if (securityContext.IsAuthenticated)
            {
                try
                {
                    writer.WriteStringValue(TimeZoneInfo.ConvertTimeFromUtc(value, securityContext.UserToken.TimeZoneInfo));
                    return;
                }
                catch (Exception e)
                {
                    var logger = _httpContextAccessor.HttpContext.RequestServices.GetRequiredService<ILogger<UserBasedDateTimeJsonConverter>>();
                    logger.LogInformation(e, e.Message);
                }
            }
        }

        writer.WriteStringValue(value);
    }
}

public class CustomJsonOptions : IConfigureOptions<JsonOptions>
{
    readonly IHttpContextAccessor _accessor;

    public FeatureConfigJsonOptions(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

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

它工作正常,但唯一奇怪的是,当我有一个包含可为 null 的 DateTime 值的自定义模型时,转换器 -> 读取方法也会命中。而且,当然对于可为 null 的类型,我不知道 return.

是什么

如果 属性 可以为空 DateTime,为什么此转换器会尝试读取数据?

编辑:

添加更多信息:

基本上我的请求模型是:

public class NewApplicationKeyRequest
{
    public Guid ApplicationId { get; set; }
    public string Description { get; set; } = string.Empty;
    public DateTime? Expired { get; set; }
}

但是当我发出请求时,CanConvert 被点击了 5 次:

  1. 对于NewApplicationKeyRequest
  2. 对于Guid -> ApplicationId
  3. 对于string -> Description
  4. 对于DateTime? -> Expired
  5. 对于 DateTime -> 不知道为什么这是由 Asp.Net 核心在幕后创建的。也许是 Expired 的某种支持字段。这就是导致问题的原因。

在添加 System.Text.Json.Serialization.JsonConverter<DateTime?> class 之后,似乎不再命中不可为 null 的版本。