Custom Date Deserialization in ASP.NET Core Web API
source link: https://blog.jonblankenship.com/2020/05/03/custom-date-deserialization-in-aspnet-core-web-api/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
This weekend I came across some oddly formatted datetimes while playing around with Twitter webhooks. When it came time to test my API endpoint to receive the Twitter event, I received a 400 response with a message indicating that one of the date fields the JSON payload could not be deserialized into a DateTimeOffset. In this post I’ll demonstrate how to write a custom converter to solve this and similar JSON deserialization problems in an ASP.NET Core Web API.
Photo by Laura Chouette on Unsplash
The Problem
Sadly, there’s not a universally accepted format for sending dates in JSON. Dates in JSON are just strings after all, and although theISO 8601 format is the most commonly used and de facto standard, it’s far from universal.
An ISO 8601 datetime looks like this: 2018-10-10T20:19:24-00:00
Twitter formats their datetimes like this: Wed Oct 10 20:19:24 +0000 2018
I don’t know if this is a format that’s used anywhere outside of Twitter or not, but I do know that the .NET JSON deserializer doesn’t know what to do with it.
When a payload with a datetime like that is POST
ed to my ASP.NET Core Web API endpoint, my API complains:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|1fb1cbcd-465ead216a3ec717.", "errors": { "$.tweet_create_events[0].created_at": [ "The JSON value could not be converted to System.DateTimeOffset. Path: $.tweet_create_events[0].created_at | LineNumber: 5 | BytePositionInLine: 49." ] } }
The Solution
I need to configure my API to deserialize datetimes in the Twitter format into a .NET DateTimeOffset
. To do this, I’ll create a custom JsonConverter
and add it to the collection of JSON converters my service wires up at start-up.
Note that I’m using the System.Text.Json
serializer that was introduced with .NET Core 3.0, not the Newtonsoft.Json
serializer.
First let’s create the custom converter.
TwitterDateTimeOffsetConverter
My custom converter derives from JsonConverter<DateTimeOffset>
. The generic type parameter specifies the data type that we’ll be deserializing to/serializing from on the .NET side.
The converter implements two methods, Read(..)
and Write(..)
, which deserialize from and serialize to our custom datetime format specified in the TwitterDateFormat
constant.
public class TwitterDateTimeOffsetConverter : JsonConverter<DateTimeOffset> { private const string TwitterDateFormat = "ddd MMM dd HH:mm:ss +ffff yyyy"; public override DateTimeOffset Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => DateTimeOffset.ParseExact(reader.GetString(), TwitterDateFormat , CultureInfo.InvariantCulture); public override void Write( Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString(TwitterDateFormat , CultureInfo.InvariantCulture)); }
Startup Configuration
The only thing left to do now is to add my new converter to the collection of JSON converters that ASP.NET Core will use when handling requests to my API. I do that in the ConfigureServices(..)
method in my Startup.cs:
public void ConfigureServices(IServiceCollection services) { services .AddMvc() .AddJsonOptions(opts => { opts.JsonSerializerOptions.Converters.Add(new TwitterDateTimeOffsetConverter()); // Add any other converters here // I typically add JsonStringEnumConverter to my APIs }); ... }
I restart my service and send a test payload to my endpoint and everything is 200 - OK
.
Life is good. :-)
– Jon
I’m a developer and solo SaaS founder who likes to build things and share what I learn with others. If you’re interested software development, launching things, or random early morning thoughts, consider following me on Twitter or subscribe to my newsletter.
Thanks for reading!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK