From 6c0188c42be9bcb5581b0e18d8230c91928c0e41 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 25 Nov 2020 07:44:11 -0700 Subject: [PATCH] Fix efcore not returning a UTC DateTime --- Jellyfin.Server.Implementations/JellyfinDb.cs | 2 + .../ModelBuilderExtensions.cs | 48 +++++++++++++++++++ .../DateTimeKindValueConverter.cs | 21 ++++++++ .../JsonDateTimeIso8601Converter.cs | 24 ---------- MediaBrowser.Common/Json/JsonDefaults.cs | 1 - 5 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 Jellyfin.Server.Implementations/ModelBuilderExtensions.cs create mode 100644 Jellyfin.Server.Implementations/ValueConverters/DateTimeKindValueConverter.cs delete mode 100644 MediaBrowser.Common/Json/Converters/JsonDateTimeIso8601Converter.cs diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs index 45e71f16e..bf8818f8d 100644 --- a/Jellyfin.Server.Implementations/JellyfinDb.cs +++ b/Jellyfin.Server.Implementations/JellyfinDb.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using System.Linq; using Jellyfin.Data.Entities; using Jellyfin.Data.Interfaces; @@ -140,6 +141,7 @@ namespace Jellyfin.Server.Implementations /// protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.SetDefaultDateTimeKind(DateTimeKind.Utc); base.OnModelCreating(modelBuilder); modelBuilder.HasDefaultSchema("jellyfin"); diff --git a/Jellyfin.Server.Implementations/ModelBuilderExtensions.cs b/Jellyfin.Server.Implementations/ModelBuilderExtensions.cs new file mode 100644 index 000000000..80ad65a42 --- /dev/null +++ b/Jellyfin.Server.Implementations/ModelBuilderExtensions.cs @@ -0,0 +1,48 @@ +using System; +using Jellyfin.Server.Implementations.ValueConverters; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Jellyfin.Server.Implementations +{ + /// + /// Model builder extensions. + /// + public static class ModelBuilderExtensions + { + /// + /// Specify value converter for the object type. + /// + /// The model builder. + /// The . + /// The type to convert. + /// The modified . + public static ModelBuilder UseValueConverterForType(this ModelBuilder modelBuilder, ValueConverter converter) + { + var type = typeof(T); + foreach (var entityType in modelBuilder.Model.GetEntityTypes()) + { + foreach (var property in entityType.GetProperties()) + { + if (property.ClrType == type) + { + property.SetValueConverter(converter); + } + } + } + + return modelBuilder; + } + + /// + /// Specify the default . + /// + /// The model builder to extend. + /// The to specify. + public static void SetDefaultDateTimeKind(this ModelBuilder modelBuilder, DateTimeKind kind) + { + modelBuilder.UseValueConverterForType(new DateTimeKindValueConverter(kind)); + modelBuilder.UseValueConverterForType(new DateTimeKindValueConverter(kind)); + } + } +} \ No newline at end of file diff --git a/Jellyfin.Server.Implementations/ValueConverters/DateTimeKindValueConverter.cs b/Jellyfin.Server.Implementations/ValueConverters/DateTimeKindValueConverter.cs new file mode 100644 index 000000000..8a510898b --- /dev/null +++ b/Jellyfin.Server.Implementations/ValueConverters/DateTimeKindValueConverter.cs @@ -0,0 +1,21 @@ +using System; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Jellyfin.Server.Implementations.ValueConverters +{ + /// + /// ValueConverter to specify kind. + /// + public class DateTimeKindValueConverter : ValueConverter + { + /// + /// Initializes a new instance of the class. + /// + /// The kind to specify. + /// The mapping hints. + public DateTimeKindValueConverter(DateTimeKind kind, ConverterMappingHints mappingHints = null) + : base(v => v.ToUniversalTime(), v => DateTime.SpecifyKind(v, kind), mappingHints) + { + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Common/Json/Converters/JsonDateTimeIso8601Converter.cs b/MediaBrowser.Common/Json/Converters/JsonDateTimeIso8601Converter.cs deleted file mode 100644 index 63b344a9d..000000000 --- a/MediaBrowser.Common/Json/Converters/JsonDateTimeIso8601Converter.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Globalization; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace MediaBrowser.Common.Json.Converters -{ - /// - /// Returns an ISO8601 formatted datetime. - /// - /// - /// Used for legacy compatibility. - /// - public class JsonDateTimeIso8601Converter : JsonConverter - { - /// - public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - => reader.GetDateTime(); - - /// - public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToString("O", CultureInfo.InvariantCulture)); - } -} diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs index 1aaf4a43b..c5050a21d 100644 --- a/MediaBrowser.Common/Json/JsonDefaults.cs +++ b/MediaBrowser.Common/Json/JsonDefaults.cs @@ -43,7 +43,6 @@ namespace MediaBrowser.Common.Json options.Converters.Add(new JsonVersionConverter()); options.Converters.Add(new JsonStringEnumConverter()); options.Converters.Add(new JsonNullableStructConverterFactory()); - options.Converters.Add(new JsonDateTimeIso8601Converter()); return options; }