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 次:
- 对于
NewApplicationKeyRequest
- 对于
Guid
-> ApplicationId
- 对于
string
-> Description
- 对于
DateTime?
-> Expired
- 对于
DateTime
-> 不知道为什么这是由 Asp.Net 核心在幕后创建的。也许是 Expired
的某种支持字段。这就是导致问题的原因。
在添加 System.Text.Json.Serialization.JsonConverter<DateTime?>
class 之后,似乎不再命中不可为 null 的版本。
所以,基本上我想创建一个自定义转换器,以便根据用户时区转换日期时间值。这是代码:
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 次:
- 对于
NewApplicationKeyRequest
- 对于
Guid
->ApplicationId
- 对于
string
->Description
- 对于
DateTime?
->Expired
- 对于
DateTime
-> 不知道为什么这是由 Asp.Net 核心在幕后创建的。也许是Expired
的某种支持字段。这就是导致问题的原因。
在添加 System.Text.Json.Serialization.JsonConverter<DateTime?>
class 之后,似乎不再命中不可为 null 的版本。