ASP.NET Core, Newtonsoft JSON serializer and DateTime handling issue
Today I encountered an interesting case. I got a report that “something changes the date format while processing data”. I started debugging our distributed system looking for the source of the problem. It took me a while, so I’d like to share this story today, so you don’t have to waste your time.
Dynamic properties in a statically typed world
One of the microservices handles the HTTP POST request which the body model is similar to this:
public class ExampleModel
{
// ...
public JObject DynamicObject { get; set; }
}
For simplicity let’s say that exactly that request model is stored in NoSQL database and could be retrieved with another endpoint.
Another service calls our application with a following HTTP request body:
{
// ...
"dynamicObject": {
"someStringProperty": "2021-04-14T08:30:00.000+0000",
"anotherStringProperty": "QWERTY"
}
}
Then requests it back and gets following response:
{
// ...
"dynamicObject": {
"someStringProperty": "2021-04-14T08:30:00Z", // wtf?!
"anotherStringProperty": "QWERTY"
}
}
As you can see, the value of someStringProperty
is different from what was sent before! In my case, this is unacceptable behavior. I need it to be exactly the same string.
Solution
After a while of debugging I found a culprit. Newtonsoft JSON serializer parsed someStringProperty
as a date. However, client service treats it as string. It turns out that this is default Newtonsoft JSON serializer behavior. It just guessed the type based on the value.
The solution is to create serializer with the following JsonSerializerSettings
:
new JsonSerializerSettings()
{
// by default it is DateParseHandling.DateTime
DateParseHandling = DateParseHandling.None
};
Now someStringProperty
will be parsed as a string. Fixed!
One more thing
While searching the internet for a solution to my problem, I came across an interesting open GitHub issue in the Newtonsoft.Json
library repository. It is closely related to my problem. At the time of writing this post, it’s still open for almost 5 years!
Take a look: “A string that looks like a date is changed when deserializing an ISerializable object #904”.
Summary
Hopefully, writing this post will save someone from a long debugging session. If you have any interesting thoughts on this, or I helped you somehow, please let me know. I will be very pleased!