Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serialisation compatibility of TimeSpan and DateTime #16205

Merged
merged 52 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1e82540
add TimeFiledTests
hyzx86 May 31, 2024
72977c2
add timespanconverter
hyzx86 May 31, 2024
628796d
fix unit test
hyzx86 May 31, 2024
ed4667e
add test recipe
hyzx86 May 31, 2024
ea68650
Merge branch 'main' into timeSpan
hyzx86 May 31, 2024
ba18386
remove test recipe
hyzx86 May 31, 2024
2415a78
Update test/OrchardCore.Tests/Data/ContentItemTests.cs
hyzx86 May 31, 2024
0243104
complete test
hyzx86 May 31, 2024
33a3fae
mege remote
hyzx86 May 31, 2024
adf8c10
Update ContentItemTests.cs
hyzx86 May 31, 2024
c519d38
Update TimeSpanJsonConverter.cs
hyzx86 May 31, 2024
ca5a1e8
Update DateTimeJsonConverter.cs
hyzx86 May 31, 2024
b60a2d8
fix unit tests
hyzx86 May 31, 2024
a626262
Merge branch 'timeSpan' of https://github.com/hyzx86/OrchardCore into…
hyzx86 May 31, 2024
b1f1405
fix tests
hyzx86 May 31, 2024
bdafe14
restore change
hyzx86 May 31, 2024
3390092
Merge branch 'main' into timeSpan
hyzx86 Jun 4, 2024
ab33aba
fix unit tests
hyzx86 Jun 4, 2024
0c99efe
Merge branch 'main' into timeSpan
MikeAlhayek Jun 5, 2024
6bca93f
Apply suggestions from code review
hishamco Jun 6, 2024
029c0fb
Merge branch 'main' into timeSpan
hishamco Jun 6, 2024
3b6f4b3
Update src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/Da…
hyzx86 Jun 6, 2024
1b8d6e5
Update src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/Ti…
hyzx86 Jun 6, 2024
70063c6
Merge branch 'main' into timeSpan
hyzx86 Jun 6, 2024
a37495f
Apply suggestions from code review
hyzx86 Jun 6, 2024
471dbea
Merge branch 'main' into timeSpan
hyzx86 Jun 6, 2024
954a3df
Update DateTimeJsonConverter.cs
hyzx86 Jun 6, 2024
14c0141
Merge branch 'main' into timeSpan
hyzx86 Jun 6, 2024
1701fab
Update DateTimeJsonConverter.cs
hyzx86 Jun 6, 2024
e2c318d
use o format
hyzx86 Jun 6, 2024
e754735
udpate DateTimeJsonConverter
hyzx86 Jun 6, 2024
8af9b5f
add different timezonre tests
hyzx86 Jun 6, 2024
0dde149
Merge branch 'main' into timeSpan
hyzx86 Jun 6, 2024
092ee26
Merge branch 'main' into timeSpan
hyzx86 Jun 6, 2024
a23465e
add utc test
hyzx86 Jun 6, 2024
76abc2a
Merge branch 'timeSpan' of https://github.com/hyzx86/OrchardCore into…
hyzx86 Jun 6, 2024
11de06d
fix utc test
hyzx86 Jun 6, 2024
f750afa
fix unitTests
hyzx86 Jun 6, 2024
e6a43aa
fix unit test
hyzx86 Jun 6, 2024
bf3e1f5
Merge branch 'main' into timeSpan
hyzx86 Jun 8, 2024
0bc1c6c
add timezone tests
hyzx86 Jun 8, 2024
71c71a5
Merge branch 'timeSpan' of https://github.com/hyzx86/OrchardCore into…
hyzx86 Jun 8, 2024
3716705
Merge branch 'main' into timeSpan
hyzx86 Jun 8, 2024
45d1b94
cleanup
MikeAlhayek Jun 8, 2024
fd8e260
Apply suggestions from code review
hyzx86 Jun 10, 2024
6041793
Merge branch 'main' into timeSpan
hyzx86 Jun 10, 2024
0675f77
Merge branch 'main' into timeSpan
hyzx86 Jun 10, 2024
d3b9f51
fix build error
hyzx86 Jun 10, 2024
6604891
Apply suggestions from code review
hishamco Jun 11, 2024
2277afd
Update src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/Da…
hyzx86 Jun 11, 2024
b9cb5fd
fix build
hyzx86 Jun 11, 2024
73ac3c6
clear
hyzx86 Jun 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/OrchardCore/OrchardCore.Abstractions/Json/JOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ static JOptions()
Default = new JsonSerializerOptions(Base);
Default.Converters.Add(new DynamicJsonConverter());
Default.Converters.Add(new PathStringJsonConverter());
Default.Converters.Add(new TimeSpanJsonConverter());
Default.Converters.Add(new DateTimeJsonConverter());

Indented = new JsonSerializerOptions(Default)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace OrchardCore.Json.Serialization;

public class DateTimeJsonConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (typeToConvert != typeof(DateTime))
{
throw new ArgumentException("Unexpected type to convert.", nameof(typeToConvert));
}

if (!reader.TryGetDateTime(out DateTime value) && DateTime.TryParse(reader.GetString()!, out value))
{
return value;
}

return value;
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace OrchardCore.Json.Serialization;

public class TimeSpanJsonConverter : JsonConverter<TimeSpan>
{
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException($"Unexpected token parsing TimeSpan. Expected a string, got '{reader.TokenType}'.");
}

var stringValue = reader.GetString();

if (TimeSpan.TryParse(stringValue, out var timeSpan))
{
return timeSpan;
}

throw new JsonException($"Unable to convert '{stringValue}' to TimeSpan.");
}

public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
=> writer.WriteStringValue(value.ToString());
}
48 changes: 47 additions & 1 deletion test/OrchardCore.Tests/Data/ContentItemTests.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
using System.Text.Json;
using System.Text.Json.Dynamic;
using System.Text.Json.Nodes;
using OrchardCore.ContentFields.Fields;
using OrchardCore.ContentManagement;
using OrchardCore.Json.Serialization;
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved

namespace OrchardCore.Tests.Data
{
public class ContentItemTests
{
/// <summary>
/// To validate <see cref="DateTimeJsonConverter"/>
/// and <seealso cref="TimeSpanJsonConverter"/>
/// </summary>
[Fact]
public void JsonNode_WhenParseCalled_ConvertShortTimeFormatToTimeField()
hyzx86 marked this conversation as resolved.
Show resolved Hide resolved
{
// Arrange
var jsonStr = """
{
"TimeFieldTest": {
"Value": "13:05"
},
"DateTimeFieldTest": {
"Value": "2024-5-31 13:05"
},
"TimezoneDateTimeFieldTest": {
"Value": "2022-12-13T21:02:18.399-05:00"
},
"DateFieldTest": {
"Value": "2024-5-31"
}
}
""";

// Act
var jobject = JsonNode.Parse(jsonStr);
var timeField = jobject.SelectNode("TimeFieldTest").ToObject<TimeField>();
var dateField = jobject.SelectNode("DateFieldTest").ToObject<DateField>();
var dateTimeField = jobject.SelectNode("DateTimeFieldTest").ToObject<DateTimeField>();
var timezoneDateTimeFieldTest = jobject.SelectNode("TimezoneDateTimeFieldTest").ToObject<DateTimeField>();

// Assert
Assert.Equal("13:05:00", timeField.Value.Value.ToString());
Assert.Equal("2024-05-31", dateField.Value.Value.ToString("yyyy-MM-dd"));
Assert.Equal("2024-05-31 13:05", dateTimeField.Value.Value.ToString("yyyy-MM-dd HH:mm"));
Assert.Equal("13:05:00", JObject.FromObject(timeField).SelectNode("Value").ToString());
Assert.Equal("2024-05-31T00:00:00Z", JObject.FromObject(dateField).SelectNode("Value").ToString());
Assert.Equal("2024-05-31T13:05:00Z", JObject.FromObject(dateTimeField).SelectNode("Value").ToString());

var utcTime = TimeZoneInfo.ConvertTimeToUtc(timezoneDateTimeFieldTest.Value.Value);
Assert.Equal("2022-12-14 02:02:18", utcTime.ToString("yyyy-MM-dd HH:mm:ss"));
}

[Fact]
public void ShouldSerializeContent()
{
Expand Down Expand Up @@ -163,7 +209,7 @@ public void ContentShouldStoreDateTimeFields()

var json = JConvert.SerializeObject(contentItem);

Assert.Contains(@"""MyPart"":{""Text"":""test"",""myField"":{""Value"":""2024-01-01T10:42:00""}}", json);
Assert.Contains(@"""MyPart"":{""Text"":""test"",""myField"":{""Value"":""2024-01-01T10:42:00Z""}}", json);
}

[Fact]
Expand Down