'date format causing model binding to fail
I recently upgraded my asp.net core web api to .NET 6. Prior to that, the model binding worked fine.
my request class:
public class FindUserRequest
{
public string EmailAddress { get; set; }
public string Id { get; set; }
public DateTime? DateOfBirth { get; set; }
}
My API controller method:
[HttpPost("FindUser")]
public IActionResult FindUser([FromBody] FindUserRequest request)
{
var response = FindUser(request);
return Ok(response);
}
The JSON being passed in the body:
{
"EmailAddress": "[email protected]",
"Id": "1234",
"DateOfBirth": "03/09/2022"
}
if I pass an ISO formatted date for the DateOfBirth property (e.g. 2022-03-09) everything is fine - but if I pass a date value like 03/09/2022 my request object completely fails to bind and the request parameter is NULL. I tried implementing a custom model binder but I can never seem to get access to the JSON in the request body when I do that. I wish there was a simple 'date format' kind of attribute I could put on the DateOfBirth property but I haven't found anything that seems to work there either. Any Ideas?
Solution 1:[1]
So the solution I ended up going with was writing a custom JsonConverter for DateTime types.
public class USDateTimeFormatConverter : JsonConverter<DateTime?>
{
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using (var jsonDoc = JsonDocument.ParseValue(ref reader))
{
string dateValue = jsonDoc.RootElement.GetString();
if (DateTime.TryParseExact(dateValue, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime isoDateTime))
return isoDateTime; // ISO8601 format worked
if (DateTime.TryParseExact(dateValue, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out DateTime usDateTime))
return usDateTime; // US MM/dd/yyyy format worked
if (DateTime.TryParse(dateValue, out DateTime otherDateTime))
return otherDateTime; // some other format worked
return null; // whatever the string was, it couldn't be recognized and parsed as any kind of date value
}
}
public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture));
}
}
Then configure it in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// This Json Serializer Converter was added due to model binding
// issues when date values are formatted like MM/dd/yyyy instead of
// ISO8601 format e.g. yyyy-MM-dd
services.AddMvc().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new USDateTimeFormatConverter());
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jamauss |
