Bind byte array from base64 config value (#43150)
authorThomas Levesque <1864281+thomaslevesque@users.noreply.github.com>
Thu, 15 Oct 2020 14:33:14 +0000 (16:33 +0200)
committerGitHub <noreply@github.com>
Thu, 15 Oct 2020 14:33:14 +0000 (07:33 -0700)
* Bind byte array from base64 config value

* Add test case for failure

* Add test for null case

* Remove unnecessary null check

Co-authored-by: Thomas Levesque <thomaslevesque@users.noreply.github.com>
src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs
src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs

index 199096a..171a8df 100644 (file)
@@ -520,6 +520,19 @@ namespace Microsoft.Extensions.Configuration
                 return true;
             }
 
+            if (type == typeof(byte[]))
+            {
+                try
+                {
+                    result = Convert.FromBase64String(value);
+                }
+                catch (FormatException ex)
+                {
+                    error = new InvalidOperationException(SR.Format(SR.Error_FailedBinding, path, type), ex);
+                }
+                return true;
+            }
+
             return false;
         }
 
index d8fb3cf..87db0c9 100644 (file)
@@ -109,6 +109,11 @@ namespace Microsoft.Extensions.Configuration.Binder.Test
             public string MyString { get; set; }
         }
 
+        public class ByteArrayOptions
+        {
+            public byte[] MyByteArray { get; set; }
+        }
+
         [Fact]
         public void CanBindIConfigurationSection()
         {
@@ -812,6 +817,55 @@ namespace Microsoft.Extensions.Configuration.Binder.Test
             Assert.Equal("hello world", options.MyString);
         }
 
+        [Fact]
+        public void CanBindByteArray()
+        {
+            var bytes = new byte[] { 1, 2, 3, 4 };
+            var dic = new Dictionary<string, string>
+            {
+                { "MyByteArray", Convert.ToBase64String(bytes) }
+            };
+            var configurationBuilder = new ConfigurationBuilder();
+            configurationBuilder.AddInMemoryCollection(dic);
+            var config = configurationBuilder.Build();
+
+            var options = config.Get<ByteArrayOptions>();
+            Assert.Equal(bytes, options.MyByteArray);
+        }
+
+        [Fact]
+        public void CanBindByteArrayWhenValueIsNull()
+        {
+            var dic = new Dictionary<string, string>
+            {
+                { "MyByteArray", null }
+            };
+            var configurationBuilder = new ConfigurationBuilder();
+            configurationBuilder.AddInMemoryCollection(dic);
+            var config = configurationBuilder.Build();
+
+            var options = config.Get<ByteArrayOptions>();
+            Assert.Equal(null, options.MyByteArray);
+        }
+
+        [Fact]
+        public void ExceptionWhenTryingToBindToByteArray()
+        {
+            var dic = new Dictionary<string, string>
+            {
+                { "MyByteArray", "(not a valid base64 string)" }
+            };
+            var configurationBuilder = new ConfigurationBuilder();
+            configurationBuilder.AddInMemoryCollection(dic);
+            var config = configurationBuilder.Build();
+
+            var exception = Assert.Throws<InvalidOperationException>(
+                () => config.Get<ByteArrayOptions>());
+            Assert.Equal(
+                SR.Format(SR.Error_FailedBinding, "MyByteArray", typeof(byte[])),
+                exception.Message);
+        }
+
         private interface ISomeInterface
         {
         }