From b25ef8cabcde83f1fe3affe7699f6e01d956034f Mon Sep 17 00:00:00 2001 From: Kirill Kovalev Date: Tue, 2 Jul 2024 19:15:47 +0300 Subject: [PATCH] Convert StringOrArrayConverter to generic version --- .../Model/AuthorizationRequest.cs | 2 +- Abblix.Oidc.Server/Model/TokenRequest.cs | 9 ++--- ...ests.cs => SingleOrArrayConverterTests.cs} | 4 +-- ...Converter.cs => SingleOrArrayConverter.cs} | 33 ++++++++++++------- 4 files changed, 26 insertions(+), 22 deletions(-) rename Abblix.Utils.UnitTests/{StringOrArrayConverterTests.cs => SingleOrArrayConverterTests.cs} (95%) rename Abblix.Utils/Json/{StringOrArrayConverter.cs => SingleOrArrayConverter.cs} (73%) diff --git a/Abblix.Oidc.Server/Model/AuthorizationRequest.cs b/Abblix.Oidc.Server/Model/AuthorizationRequest.cs index 6812216..a3be487 100644 --- a/Abblix.Oidc.Server/Model/AuthorizationRequest.cs +++ b/Abblix.Oidc.Server/Model/AuthorizationRequest.cs @@ -178,7 +178,7 @@ public record AuthorizationRequest /// resource. /// [JsonPropertyName(Parameters.Resource)] - [JsonConverter(typeof(StringOrArrayConverter))] + [JsonConverter(typeof(SingleOrArrayConverter))] public Uri[]? Resources { get; set; } public static class Parameters diff --git a/Abblix.Oidc.Server/Model/TokenRequest.cs b/Abblix.Oidc.Server/Model/TokenRequest.cs index aa8e253..44b0dda 100644 --- a/Abblix.Oidc.Server/Model/TokenRequest.cs +++ b/Abblix.Oidc.Server/Model/TokenRequest.cs @@ -81,7 +81,7 @@ public static class Parameters /// Defined in RFC 8707. /// [JsonPropertyName(Parameters.Resource)] - [JsonConverter(typeof(StringOrArrayConverter))] + [JsonConverter(typeof(SingleOrArrayConverter))] public Uri[]? Resources { get; set; } /// @@ -94,12 +94,7 @@ public static class Parameters /// The scope of the access request, expressed as a list of space-delimited, case-sensitive strings. /// [JsonPropertyName(Parameters.Scope)] - [AllowedValues( - Scopes.OpenId, - Scopes.Profile, - Scopes.Email, - Scopes.Phone, - Scopes.OfflineAccess)] + [AllowedValues(Scopes.OpenId, Scopes.Profile, Scopes.Email, Scopes.Phone, Scopes.OfflineAccess)] public string[] Scope { get; set; } = Array.Empty(); /// diff --git a/Abblix.Utils.UnitTests/StringOrArrayConverterTests.cs b/Abblix.Utils.UnitTests/SingleOrArrayConverterTests.cs similarity index 95% rename from Abblix.Utils.UnitTests/StringOrArrayConverterTests.cs rename to Abblix.Utils.UnitTests/SingleOrArrayConverterTests.cs index c80dfbc..0af8030 100644 --- a/Abblix.Utils.UnitTests/StringOrArrayConverterTests.cs +++ b/Abblix.Utils.UnitTests/SingleOrArrayConverterTests.cs @@ -26,9 +26,9 @@ namespace Abblix.Utils.UnitTests; -public class StringOrArrayConverterTests +public class SingleOrArrayConverterTests { - private readonly StringOrArrayConverter _converter = new(); + private readonly SingleOrArrayConverter _converter = new(); [Theory] [InlineData("\"singleString\"", new[] { "singleString" })] diff --git a/Abblix.Utils/Json/StringOrArrayConverter.cs b/Abblix.Utils/Json/SingleOrArrayConverter.cs similarity index 73% rename from Abblix.Utils/Json/StringOrArrayConverter.cs rename to Abblix.Utils/Json/SingleOrArrayConverter.cs index 5fc0dc3..e860b24 100644 --- a/Abblix.Utils/Json/StringOrArrayConverter.cs +++ b/Abblix.Utils/Json/SingleOrArrayConverter.cs @@ -20,8 +20,6 @@ // CONTACT: For license inquiries or permissions, contact Abblix LLP at // info@abblix.com -using System.Collections.Generic; - namespace Abblix.Utils.Json; using System; @@ -32,7 +30,7 @@ namespace Abblix.Utils.Json; /// A JSON converter that handles deserialization and serialization of a JSON value /// that could either be a single string or an array of strings. /// -public class StringOrArrayConverter : JsonConverter +public class SingleOrArrayConverter : JsonConverter { /// /// Reads and converts the JSON to a string array. @@ -45,15 +43,19 @@ public class StringOrArrayConverter : JsonConverter /// An array of strings parsed from the JSON input. /// Thrown if an unexpected token type is encountered. - public override string[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var elementType = typeof(T); + var converter = (JsonConverter)options.GetConverter(elementType) + ?? throw new JsonException($"No converter found for {elementType}"); + switch (reader.TokenType) { case JsonTokenType.Null: return null; case JsonTokenType.String: - return new[] { ReadStringFrom(reader) }; + return new[] { ReadFrom(ref reader, elementType, converter, options) }; case JsonTokenType.StartArray: break; @@ -62,7 +64,7 @@ public class StringOrArrayConverter : JsonConverter throw new JsonException("Unexpected token type."); } - var values = new List(); + var values = new List(); while (reader.Read()) { switch (reader.TokenType) @@ -71,7 +73,7 @@ public class StringOrArrayConverter : JsonConverter break; case JsonTokenType.String: - values.Add(ReadStringFrom(reader)); + values.Add(ReadFrom(ref reader, elementType, converter, options)); break; default: @@ -80,8 +82,11 @@ public class StringOrArrayConverter : JsonConverter } return values.ToArray(); - static string ReadStringFrom(Utf8JsonReader reader) - => reader.GetString() ?? throw new JsonException("Null values are not allowed"); + static T ReadFrom(ref Utf8JsonReader reader, Type elementType, JsonConverter converter, JsonSerializerOptions options) + { + return converter.Read(ref reader, elementType, options) + ?? throw new JsonException("Null values are not allowed"); + } } /// @@ -93,8 +98,12 @@ static string ReadStringFrom(Utf8JsonReader reader) /// The string array to write. /// Options for the serializer. /// Thrown if the writer or value is null. - public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options) { + var elementType = typeof(T); + var converter = (JsonConverter)options.GetConverter(elementType) + ?? throw new JsonException($"No converter found for {elementType}"); + if (value == null) { writer.WriteNullValue(); @@ -104,14 +113,14 @@ public override void Write(Utf8JsonWriter writer, string[]? value, JsonSerialize switch (value.Length) { case 1: - writer.WriteStringValue(value[0]); + converter.Write(writer, value[0], options); break; default: writer.WriteStartArray(); foreach (var item in value) { - writer.WriteStringValue(item); + converter.Write(writer, item, options); } writer.WriteEndArray(); break;