From 5f93d602779c51d0ef9e4ba39e289590f339193b Mon Sep 17 00:00:00 2001 From: Sergey Gut Date: Sat, 25 Dec 2021 23:52:09 +0400 Subject: [PATCH] Fix user option values on .NET 5+ --- Core/Data/BotUserValue.cs | 42 +++++------ Core/Extensions/RepositoryExtension.cs | 11 ++- Core/GeneralHandler.cs | 1 + .../20211225192324_AddValueType.Designer.cs | 73 +++++++++++++++++++ .../Migrations/20211225192324_AddValueType.cs | 36 +++++++++ Core/Migrations/CoreContextModelSnapshot.cs | 7 +- 6 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 Core/Migrations/20211225192324_AddValueType.Designer.cs create mode 100644 Core/Migrations/20211225192324_AddValueType.cs diff --git a/Core/Data/BotUserValue.cs b/Core/Data/BotUserValue.cs index 9a95827..f4f1622 100644 --- a/Core/Data/BotUserValue.cs +++ b/Core/Data/BotUserValue.cs @@ -1,7 +1,10 @@ using System; using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.Serialization.Formatters.Binary; +using System.Text.Json; +using System.Xml.Serialization; namespace Kruzya.TelegramBot.Core.Data { @@ -13,30 +16,27 @@ namespace Kruzya.TelegramBot.Core.Data public BotUser BotUser { get; set; } public string Name { get; set; } - public byte[] Value - { - get - { - var fmt = new BinaryFormatter(); - using var memStream = new MemoryStream(); - fmt.Serialize(memStream, data); - - return memStream.ToArray(); - } - set - { - var fmt = new BinaryFormatter(); - using var memStream = new MemoryStream(); - memStream.Write(value); - memStream.Position = 0; + public string ValueType { get; set; } - data = fmt.Deserialize(memStream); + public byte[] Value { get; set; } + + public T GetValue(T defVal = default) + { + try + { + return JsonSerializer.Deserialize(new ReadOnlySpan(Value)); + } + catch (Exception) + { + return defVal; } } - [NonSerialized] public object data; - - public T GetValue() => (T) data; - public void SetValue(T value) => data = value; + public void SetValue(T value) + { + Value = JsonSerializer.SerializeToUtf8Bytes(value, new JsonSerializerOptions { WriteIndented = false, + IgnoreNullValues = true }); + ValueType = value.GetType().FullName; + } } } \ No newline at end of file diff --git a/Core/Extensions/RepositoryExtension.cs b/Core/Extensions/RepositoryExtension.cs index db33374..0c2b834 100644 --- a/Core/Extensions/RepositoryExtension.cs +++ b/Core/Extensions/RepositoryExtension.cs @@ -30,8 +30,14 @@ namespace Kruzya.TelegramBot.Core.Extensions /// /// /// Entity for marking as modified. - public static void MarkAsModified(this DbContext dbContext, object entity) => - dbContext.Entry(entity).State = EntityState.Modified; + public static void MarkAsModified(this DbContext dbContext, object entity) + { + var entry = dbContext.Entry(entity); + if (entry.State == EntityState.Added) + return; + + entry.State = EntityState.Modified; + } #endregion @@ -97,6 +103,7 @@ namespace Kruzya.TelegramBot.Core.Extensions if (opt == null) { opt = repository.Create(); + opt.Name = option; opt.BotUser = await repository.GetService().Users.FindOrCreate(chatId, userId); } diff --git a/Core/GeneralHandler.cs b/Core/GeneralHandler.cs index d17a472..163cd32 100644 --- a/Core/GeneralHandler.cs +++ b/Core/GeneralHandler.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using BotFramework; using BotFramework.Attributes; using Kruzya.TelegramBot.Core.Data; +using Kruzya.TelegramBot.Core.Extensions; using Microsoft.EntityFrameworkCore; using Telegram.Bot.Types; diff --git a/Core/Migrations/20211225192324_AddValueType.Designer.cs b/Core/Migrations/20211225192324_AddValueType.Designer.cs new file mode 100644 index 0000000..059b4ef --- /dev/null +++ b/Core/Migrations/20211225192324_AddValueType.Designer.cs @@ -0,0 +1,73 @@ +// +using System; +using Kruzya.TelegramBot.Core.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kruzya.TelegramBot.Core.Migrations +{ + [DbContext(typeof(CoreContext))] + [Migration("20211225192324_AddValueType")] + partial class AddValueType + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUser", b => + { + b.Property("BotUserId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChatId") + .HasColumnType("bigint"); + + b.Property("UserId") + .HasColumnType("bigint"); + + b.HasKey("BotUserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.Property("BotUserValueId") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BotUserId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longblob"); + + b.Property("ValueType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("BotUserValueId"); + + b.HasIndex("BotUserId"); + + b.ToTable("UserValues"); + }); + + modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b => + { + b.HasOne("Kruzya.TelegramBot.Core.Data.BotUser", "BotUser") + .WithMany() + .HasForeignKey("BotUserId"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Core/Migrations/20211225192324_AddValueType.cs b/Core/Migrations/20211225192324_AddValueType.cs new file mode 100644 index 0000000..acb070b --- /dev/null +++ b/Core/Migrations/20211225192324_AddValueType.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Kruzya.TelegramBot.Core.Migrations +{ + public partial class AddValueType : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ValueType", + table: "UserValues", + nullable: true); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "Users", + nullable: false, + oldClrType: typeof(int), + oldType: "int"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ValueType", + table: "UserValues"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "Users", + type: "int", + nullable: false, + oldClrType: typeof(long)); + } + } +} diff --git a/Core/Migrations/CoreContextModelSnapshot.cs b/Core/Migrations/CoreContextModelSnapshot.cs index 827b255..8545ed9 100644 --- a/Core/Migrations/CoreContextModelSnapshot.cs +++ b/Core/Migrations/CoreContextModelSnapshot.cs @@ -26,8 +26,8 @@ namespace Kruzya.TelegramBot.Core.Migrations b.Property("ChatId") .HasColumnType("bigint"); - b.Property("UserId") - .HasColumnType("int"); + b.Property("UserId") + .HasColumnType("bigint"); b.HasKey("BotUserId"); @@ -49,6 +49,9 @@ namespace Kruzya.TelegramBot.Core.Migrations b.Property("Value") .HasColumnType("longblob"); + b.Property("ValueType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + b.HasKey("BotUserValueId"); b.HasIndex("BotUserId");