From cca30e7027a262fc3c40c93c80f6ca6f0a75674e Mon Sep 17 00:00:00 2001 From: Rory& Date: Tue, 8 Sep 2026 01:25:34 +0200 Subject: [PATCH] Experimental: try using JsonPolymorphic rather than custom JsonConvert logic --- .../Models/Spacebar.Models.Generic/Member.cs | 144 +----------------- .../Controllers/Op14Controller.cs | 2 +- 2 files changed, 4 insertions(+), 142 deletions(-) diff --git a/extra/admin-api/Models/Spacebar.Models.Generic/Member.cs b/extra/admin-api/Models/Spacebar.Models.Generic/Member.cs index 9e003e73b..d418ab058 100644 --- a/extra/admin-api/Models/Spacebar.Models.Generic/Member.cs +++ b/extra/admin-api/Models/Spacebar.Models.Generic/Member.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; @@ -9,7 +8,9 @@ namespace Spacebar.Models.Generic; [DebuggerDisplay("{User.Id} ({User.Username}#{User.Discriminator})")] [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")] [SuppressMessage("ReSharper", "PropertyCanBeMadeInitOnly.Global")] -[JsonConverter(typeof(MemberJsonConverter))] +[JsonPolymorphic] +[JsonDerivedType(typeof(Member))] +[JsonDerivedType(typeof(MemberWithPresence))] public class Member { [JsonPropertyName("user")] @@ -45,143 +46,4 @@ public class MemberWithPresence : Member { [JsonPropertyName("presence")] public Presence? Presence { get; set; } -} - -public class MemberJsonConverter : JsonConverter -{ - public override Member? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType == JsonTokenType.Null) - return null; - - using var document = JsonDocument.ParseValue(ref reader); - var jsonObject = document.RootElement; - if (jsonObject.ValueKind != JsonValueKind.Object) - throw new JsonException("Expected member payload to be a JSON object."); - - var hasPresence = jsonObject.TryGetProperty("presence", out _); - Member member = hasPresence - ? new MemberWithPresence { User = null! } - : new Member { User = null! }; - var hasUser = false; - - foreach (var property in jsonObject.EnumerateObject()) - { - switch (property.Name) - { - case "user": - member.User = property.Value.Deserialize(options) ?? throw new JsonException("The required member user field is invalid."); - hasUser = true; - - break; - case "nick": - member.Nick = property.Value.ValueKind == JsonValueKind.Null ? null : property.Value.GetString(); - break; - case "avatar": - member.Avatar = property.Value.ValueKind == JsonValueKind.Null ? null : property.Value.GetString(); - break; - case "avatar_decoration_data": - member.AvatarDecorationData = property.Value.ValueKind == JsonValueKind.Null ? null : JsonNode.Parse(property.Value.GetRawText()) as JsonObject; - break; - case "collectibles": - member.Collectibles = property.Value.ValueKind == JsonValueKind.Null ? null : JsonNode.Parse(property.Value.GetRawText()) as JsonObject; - break; - case "display_name_styles": - if (property.Value.ValueKind != JsonValueKind.Null) - member.DisplayNameStyles = property.Value.Deserialize(options); - break; - case "banner": - member.Banner = property.Value.ValueKind == JsonValueKind.Null ? null : property.Value.GetString(); - break; - case "bio": - member.Bio = property.Value.ValueKind == JsonValueKind.Null ? null : property.Value.GetString(); - break; - case "roles": - if (property.Value.ValueKind == JsonValueKind.Null) - { - member.Roles = null; - break; - } - - if (property.Value.ValueKind != JsonValueKind.Array) - throw new JsonException("Expected roles to be an array."); - - member.Roles = new List(); - foreach (var role in property.Value.EnumerateArray()) - { - switch (role.ValueKind) - { - case JsonValueKind.Number: - member.Roles.Add(role.GetInt64()); - break; - case JsonValueKind.String: - if (!long.TryParse(role.GetString(), out var roleId)) - throw new JsonException("Invalid role id."); - member.Roles.Add(roleId); - break; - default: - throw new JsonException("Invalid role id value kind."); - } - } - - break; - case "presence": - if (member is MemberWithPresence memberWithPresence && property.Value.ValueKind != JsonValueKind.Null) - memberWithPresence.Presence = property.Value.Deserialize(options); - break; - } - } - - if (!hasUser) - throw new JsonException("The required member user field is missing."); - - return member; - } - - public override void Write(Utf8JsonWriter writer, Member value, JsonSerializerOptions options) - { - writer.WriteStartObject(); - { - writer.WritePropertyName("user"); - JsonSerializer.Serialize(writer, value.User); - - if (value.Nick != null) writer.WriteString("nick", value.Nick); - if (value.Avatar != null) writer.WriteString("avatar", value.Avatar); - - if (value.AvatarDecorationData != null) - { - writer.WritePropertyName("avatar_decoration_data"); - JsonSerializer.Serialize(writer, value.AvatarDecorationData); - } - - if (value.Collectibles != null) - { - writer.WritePropertyName("collectibles"); - JsonSerializer.Serialize(writer, value.Collectibles); - } - - writer.WritePropertyName("display_name_styles"); - if (value.DisplayNameStyles != null) - { - JsonSerializer.Serialize(writer, value.DisplayNameStyles); - } - else writer.WriteNullValue(); - - if (value.Banner != null) writer.WriteString("banner", value.Banner); - if (value.Bio != null) writer.WriteString("bio", value.Bio); - - if (value.Roles != null) - { - writer.WritePropertyName("roles"); - JsonSerializer.Serialize(writer, value.Roles); - } - - if (value is MemberWithPresence mwp && mwp.Presence != null) - { - writer.WritePropertyName("presence"); - JsonSerializer.Serialize(writer, mwp.Presence); - } - } - writer.WriteEndObject(); - } } \ No newline at end of file diff --git a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs index ed1464b31..0ef4a8763 100644 --- a/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs +++ b/extra/admin-api/Spacebar.Offload/Controllers/Op14Controller.cs @@ -29,7 +29,7 @@ public class Op14Controller(ILogger logger, SpacebarAspNetAuthen public async IAsyncEnumerable DoLazyRequest([FromBody] LazyRequest payload) { var user = await TraceResult.TraceAsync("getAuthUser", () => authService.GetCurrentUserAsync(Request)); - var session = await TraceResult.TraceAsync("getAuthSession", () => authService.GetCurrentSessionAsync(Request)); + // var session = await TraceResult.TraceAsync("getAuthSession", () => authService.GetCurrentSessionAsync(Request)); if (!await db.Members.AsNoTracking().AnyAsync(m => m.GuildId == payload.GuildId && m.Id == user.Result.Id)) {