Skip to content

System.Text.Json.JsonSerializer cannot deserialize Date and Time types using default converters #580

@n0spaces

Description

@n0spaces

Hello!

The default JSON converters in System.Text.Json do not work with the Date or Time types. These types are serialized as objects containing the read-only properties. Those properties are not set when deserializing, so they get the default values. Same issue applies with Newtonsoft.Json.

This is a problem when using third-party libraries that can't use KiotaJsonSerializer or the extension methods. My specific use case is using Temporal, which serializes values returned from activities and deserializes them later. I had an activity that returned a Kiota-generated model with a date, but the date later deserialized to 0001-01-01. This is easy to fix by creating a type that uses DateOnly or registering a new JsonConverter, but the bug confused me for a while.

This was briefly mentioned in #282 which was closed due to no response. That issue also mentions serializing enums, which I haven't tried.

Demo: (.NET 9.0.10 using Microsoft.Kiota.Abstractions v1.20.1)

var date = new Date(DateTime.Now);

var dateSerialized = JsonSerializer.Serialize(date);
// {
//    "DateTime": "2025-10-24T10:18:54.5003283-05:00",
//    "Year": 2025,
//    "Month": 10,
//    "Day": 24
// }

var dateDeserialized = JsonSerializer.Deserialize<Date>(dateSerialized);
// {
//    DateTime = 1/1/0001 12:00:00 AM
//    Year = 1
//    Month = 1
//    Day = 1
// }

var time = new Time(DateTime.Now);

var timeSerialized = JsonSerializer.Serialize(time);
// {
//    "DateTime": "2025-10-24T10:18:54.5090402-05:00",
//    "Hour": 10,
//    "Minute": 18,
//    "Second": 54
// }

var timeDeserialized = JsonSerializer.Deserialize<Time>(timeSerialized);
// {
//    DateTime = 1/1/0001 12:00:00 AM
//    Hour = 1
//    Minute = 1
//    Second = 1
// }

This could be fixed a couple different ways:

  1. Change the DateTime property from { get; } to { get; init; }. This also fixes deserialization with Newtonsoft.Json. I can't think of any downside.
  2. Add [JsonConstructor] to one of the constructors so the JSON properties are used in the constructor arguments.
  3. Provide JsonConverters that mimic KiotaJsonSerializer. This would also fix serialization so they are written as strings instead of objects, but that might technically be a breaking change.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status

Needs Triage 🔍

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions