From: Steve Harter Date: Fri, 31 May 2019 18:55:12 +0000 (-0700) Subject: Add (de)serialization support for Base64 string as Byte array (dotnet/corefx#38106) X-Git-Tag: submit/tizen/20210909.063632~11031^2~1433 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc3e3319d841bb4654788fe019f0d4d944d60b85;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add (de)serialization support for Base64 string as Byte array (dotnet/corefx#38106) * Add (de)serialization for Base64 string as Byte array * Review feedback Commit migrated from https://github.com/dotnet/corefx/commit/a7ad25c7749cbd8ede10119a2e0ab43276192d8e --- diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 3fde4c3..3fc23f5 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -57,6 +57,7 @@ + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultConverters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultConverters.cs index bc33704..8bc855b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultConverters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/DefaultConverters.cs @@ -11,9 +11,10 @@ namespace System.Text.Json.Serialization.Converters { private static readonly Dictionary s_valueConverters = new Dictionary() { + { typeof(byte[]), new JsonValueConverterByteArray() }, { typeof(DateTimeOffset), new JsonValueConverterDateTimeOffset() }, { typeof(Guid), new JsonValueConverterGuid() }, - { typeof(JsonElement), new JsonValueConverterJsonElement() } + { typeof(JsonElement), new JsonValueConverterJsonElement() }, }; internal static bool IsValueConvertable(Type type) @@ -32,6 +33,7 @@ namespace System.Text.Json.Serialization.Converters new object[] { false }, culture: null); } + TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs new file mode 100644 index 0000000..b232293 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByteArray.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization.Policies; + +namespace System.Text.Json.Serialization.Converters +{ + internal sealed class JsonValueConverterByteArray : JsonValueConverter + { + public override bool TryRead(Type valueType, ref Utf8JsonReader reader, out byte[] value) + { + if (reader.TokenType != JsonTokenType.String) + { + value = default; + return false; + } + + return reader.TryGetBytesFromBase64(out value); + } + + public override void Write(byte[] value, Utf8JsonWriter writer) + { + writer.WriteBase64StringValue(value); + } + + public override void Write(JsonEncodedText propertyName, byte[] value, Utf8JsonWriter writer) + { + writer.WriteBase64String(propertyName, value); + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs index 22be588..222d1cb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoCommon.cs @@ -50,7 +50,6 @@ namespace System.Text.Json.Serialization IsPropertyPolicy = true; HasGetter = true; HasSetter = true; - ValueConverter = DefaultConverters.s_converter; } GetPolicies(); diff --git a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs index d87f133..aeddfbb 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Array.ReadTests.cs @@ -26,6 +26,78 @@ namespace System.Text.Json.Serialization.Tests } [Fact] + public static void ReadNullByteArray() + { + string json = @"null"; + byte[] arr = JsonSerializer.Parse(json); + Assert.Null(arr); + } + + [Fact] + public static void ReadEmptyByteArray() + { + string json = @""""""; + byte[] arr = JsonSerializer.Parse(json); + Assert.Equal(0, arr.Length); + } + + [Fact] + public static void ReadByteArray() + { + string json = $"\"{Convert.ToBase64String(new byte[] { 1, 2 })}\""; + byte[] arr = JsonSerializer.Parse(json); + + Assert.Equal(2, arr.Length); + Assert.Equal(1, arr[0]); + Assert.Equal(2, arr[1]); + } + + [Fact] + public static void Read2dByteArray() + { + // Baseline for comparison. + Assert.Equal("AQI=", Convert.ToBase64String(new byte[] { 1, 2 })); + + string json = "[\"AQI=\",\"AQI=\"]"; + byte[][] arr = JsonSerializer.Parse(json); + Assert.Equal(2, arr.Length); + + Assert.Equal(2, arr[0].Length); + Assert.Equal(1, arr[0][0]); + Assert.Equal(2, arr[0][1]); + + Assert.Equal(2, arr[1].Length); + Assert.Equal(1, arr[1][0]); + Assert.Equal(2, arr[1][1]); + } + + [Fact] + public static void ReadByteArrayFail() + { + Assert.Throws(() => JsonSerializer.Parse(@"""1""")); + Assert.Throws(() => JsonSerializer.Parse(@"""A===""")); + } + + [Fact] + public static void ReadByteArrayAsJsonArrayFail() + { + string json = $"[1, 2]"; + // Currently no support deserializing JSON arrays as byte[] - only Base64 string. + Assert.Throws(() => JsonSerializer.Parse(json)); + } + + [Fact] + public static void ReadByteListAsJsonArray() + { + string json = $"[1, 2]"; + List list = JsonSerializer.Parse>(json); + + Assert.Equal(2, list.Count); + Assert.Equal(1, list[0]); + Assert.Equal(2, list[1]); + } + + [Fact] public static void DeserializeObjectArray_36167() { // https://github.com/dotnet/corefx/issues/36167 diff --git a/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs index 65ef8bb..7af9123 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Array.WriteTests.cs @@ -26,6 +26,39 @@ namespace System.Text.Json.Serialization.Tests } [Fact] + public static void WriteNullByteArray() + { + byte[] input = null; + string json = JsonSerializer.ToString(input); + Assert.Equal($"null", json); + } + + [Fact] + public static void WriteEmptyByteArray() + { + var input = new byte[] {}; + string json = JsonSerializer.ToString(input); + Assert.Equal(@"""""", json); + } + + [Fact] + public static void WriteByteArray() + { + var input = new byte[] { 1, 2 }; + string json = JsonSerializer.ToString(input); + Assert.Equal($"\"{Convert.ToBase64String(input)}\"", json); + } + + [Fact] + public static void WriteTwo2dByteArray() + { + var inner = new byte[] { 1, 2 }; + var outer = new byte[2][] { inner, inner }; + string json = JsonSerializer.ToString(outer); + Assert.Equal($"[\"{Convert.ToBase64String(inner)}\",\"{Convert.ToBase64String(inner)}\"]", json); + } + + [Fact] public static void WriteObjectArray() { string json; diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestClass.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestClass.cs index ba69ea6..31a28a5 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestClass.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestClass.cs @@ -111,7 +111,7 @@ namespace System.Text.Json.Serialization.Tests @"""MyUInt16Array"" : [4]," + @"""MyUInt32Array"" : [5]," + @"""MyUInt64Array"" : [6]," + - @"""MyByteArray"" : [7]," + + @"""MyByteArray"" : ""Bw==""," + // Base64 encoded value of 7 @"""MySByteArray"" : [8]," + @"""MyCharArray"" : [""a""]," + @"""MyStringArray"" : [""Hello""]," + diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestStruct.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestStruct.cs index a5fac97..3a40d7f 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestStruct.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses.SimpleTestStruct.cs @@ -83,7 +83,7 @@ namespace System.Text.Json.Serialization.Tests @"""MyUInt16Array"" : [4]," + @"""MyUInt32Array"" : [5]," + @"""MyUInt64Array"" : [6]," + - @"""MyByteArray"" : [7]," + + @"""MyByteArray"" : ""Bw==""," + // Base64 encoded value of 7 @"""MySByteArray"" : [8]," + @"""MyCharArray"" : [""a""]," + @"""MyStringArray"" : [""Hello""]," +