So, basically I wanted to create a custom converter in order to convert datetime values according to user timezone. Here is the code:
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));
}
}
It works fine but the only odd thing is that when I have a custom model which contains a nullable DateTime value, the converter -> read method will hit as well. And, of course for nullable types I dont know what to return.
Why would this converter try to read the data if the property is nullable DateTime ?
EDIT:
Add some more info:
Basically my request model is:
public class NewApplicationKeyRequest
{
public Guid ApplicationId { get; set; }
public string Description { get; set; } = string.Empty;
public DateTime? Expired { get; set; }
}
But when I do the request the CanConvert
is hit 5 times:
NewApplicationKeyRequest
Guid
-> ApplicationId
string
-> Description
DateTime?
-> Expired
DateTime
-> No idea why this is somehow created under the hood by Asp.Net core. Maybe is some sort of backing field for the Expired
. And this is the one causing the problem.After adding also a System.Text.Json.Serialization.JsonConverter<DateTime?>
class it seems that the non-nullable version was not hit anymore.