diff --git a/src/serialization/json/DateJsonConverter.cs b/src/serialization/json/DateJsonConverter.cs new file mode 100644 index 00000000..c0778ab1 --- /dev/null +++ b/src/serialization/json/DateJsonConverter.cs @@ -0,0 +1,44 @@ +// ------------------------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. +// ------------------------------------------------------------------------------ + +using System; +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Kiota.Abstractions; + +namespace Microsoft.Kiota.Serialization.Json; + +/// +/// Converts a Date object or value to/from JSON. +/// +public class DateJsonConverter : JsonConverter +{ + /// + public override Date Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if(reader.TokenType == JsonTokenType.Null) + return default; + + if(reader.TokenType == JsonTokenType.String) + { + var stringValue = reader.GetString(); + if(string.IsNullOrEmpty(stringValue)) + return default; + + if(DateTime.TryParse(stringValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime)) + return new Date(dateTime); + + throw new JsonException($"Unable to parse '{stringValue}' as a Date."); + } + + throw new JsonException($"Unexpected token type '{reader.TokenType}' when reading Date."); + } + + /// + public override void Write(Utf8JsonWriter writer, Date value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString()); + } +} diff --git a/src/serialization/json/KiotaJsonSerializationContext.cs b/src/serialization/json/KiotaJsonSerializationContext.cs index c9121fd5..0ec48f5e 100644 --- a/src/serialization/json/KiotaJsonSerializationContext.cs +++ b/src/serialization/json/KiotaJsonSerializationContext.cs @@ -1,4 +1,5 @@ using System; +using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Kiota.Abstractions; @@ -34,4 +35,24 @@ namespace Microsoft.Kiota.Serialization.Json; [JsonSerializable(typeof(Date?))] [JsonSerializable(typeof(Time))] [JsonSerializable(typeof(Time?))] -public partial class KiotaJsonSerializationContext : JsonSerializerContext; +public partial class KiotaJsonSerializationContext : JsonSerializerContext +{ + private static JsonSerializerOptions? _defaultOptionsWithConverters; + + /// + /// Gets the default with Date and Time converters registered. + /// + public static JsonSerializerOptions DefaultOptionsWithConverters + { + get + { + if(_defaultOptionsWithConverters == null) + { + _defaultOptionsWithConverters = new JsonSerializerOptions(Default.Options); + _defaultOptionsWithConverters.Converters.Add(new DateJsonConverter()); + _defaultOptionsWithConverters.Converters.Add(new TimeJsonConverter()); + } + return _defaultOptionsWithConverters; + } + } +} diff --git a/src/serialization/json/README.md b/src/serialization/json/README.md index 96525639..abe05a67 100644 --- a/src/serialization/json/README.md +++ b/src/serialization/json/README.md @@ -12,6 +12,50 @@ Read more about Kiota [here](https://github.com/microsoft/kiota/blob/main/README dotnet add package Microsoft.Kiota.Serialization.Json ``` +## Using Date and Time Converters with System.Text.Json + +The library provides `DateJsonConverter` and `TimeJsonConverter` to enable serialization and deserialization of Kiota's `Date` and `Time` types when using `System.Text.Json.JsonSerializer` directly (outside of Kiota's serialization infrastructure). + +### Option 1: Using DefaultOptionsWithConverters + +The simplest approach is to use the pre-configured options with converters: + +```csharp +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Serialization.Json; +using System.Text.Json; + +var date = new Date(2025, 10, 24); +var json = JsonSerializer.Serialize(date, KiotaJsonSerializationContext.DefaultOptionsWithConverters); +// Output: "2025-10-24" + +var deserialized = JsonSerializer.Deserialize(json, KiotaJsonSerializationContext.DefaultOptionsWithConverters); +// deserialized.Year == 2025, deserialized.Month == 10, deserialized.Day == 24 +``` + +### Option 2: Manually Registering Converters + +You can also manually register the converters with your own `JsonSerializerOptions`: + +```csharp +using Microsoft.Kiota.Abstractions; +using Microsoft.Kiota.Serialization.Json; +using System.Text.Json; + +var options = new JsonSerializerOptions(); +options.Converters.Add(new DateJsonConverter()); +options.Converters.Add(new TimeJsonConverter()); + +var time = new Time(10, 18, 54); +var json = JsonSerializer.Serialize(time, options); +// Output: "10:18:54" + +var deserialized = JsonSerializer.Deserialize