Skip to content

byte[] de/serialization behaviour change #49728

@petrna

Description

@petrna

Library

System.Text.Json

Summary

Some JSON containing null, where value maps to type byte[] - initially serialized by 4.7.2 (or Newtonsoft) - can't be deserialized with versions after 4.7.2 without a custom converter as exceptions are thrown.

Description

Behaviour discrepancy after upgrading from 4.7.2.
The discrepancy is present as early as 5.0.0-preview.1.20120.5. Same result with latest 6.0.0-preview.2.21154.6

4.7.2 Serialization behaviour:

        [Fact]
        public void Serialize_ByteArray_ShouldBeNull()
        {
            var obj = (byte[]) null;
            var result = JsonSerializer.Serialize(obj);
            Assert.Equal("null", result);
        }
        
        [Fact]
        public void Serialize_ByteArrayProperty_ShouldBeNull()
        {
            byte[] data = null;
            var objc = new {MyData = data};
            var result = JsonSerializer.Serialize(objc);
            Assert.Equal("{\"MyData\":null}", result);
        }

        [Fact] // Fails after 4.7.2
        public void Serialize_ByteArrayOfArray_ShouldBeArrayOfNull()
        {
            var obj = new[] {(byte[]) null};
            var result = JsonSerializer.Serialize(obj);
            Assert.Equal("[null]", result);
        }

        [Fact] // Fails after 4.7.2
        public void Serialize_ByteArrayDictValue_ShouldBeNull()
        {
            var obj = new Dictionary<string, byte[]>()
            {
                {"test", (byte[])null}
            };
            var result = JsonSerializer.Serialize(obj);
            Assert.Equal("{\"test\":null}", result);
        }

Any 5.x and 6.x package since then converts null of type byte[] to "" instead of null within a collection.
4.7.2 has identical behaviour in this regard to Newtonsoft.Json (12.0.3)

Deserialization is also no longer working, as the following code now throws exception:

        [Fact]
        public void Deserialize_ByteArrayDictValue_ShouldBeNull()
        {
            var result = JsonSerializer.Deserialize<Dictionary<string, byte[]>>("{\"test\":null}");
            Assert.Equal(null, result["test"]);
        }
Exception thrown:
System.InvalidOperationException
Cannot get the value of a token type 'Null' as a string.
   at System.Text.Json.Utf8JsonReader.TryGetBytesFromBase64(Byte[]& value)
   at System.Text.Json.Utf8JsonReader.GetBytesFromBase64()
   at System.Text.Json.Serialization.Converters.ByteArrayConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
   at System.Text.Json.Serialization.Converters.DictionaryDefaultConverter`3.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions