Search code examples
c#system.text.json

The JSON value could not be converted to System.Byte[]


I'm getting the following exception when trying to deserialize the following JSON when dealing with byte arrays, what's wrong?

public class Program
{
    public static void Main()
    {
        var root = JsonSerializer.Deserialize<JsonRoot>(@"{ ""ByteArray"": [1] } ");
    }

    public class JsonRoot
    {
        public byte[] ByteArray {get;set;}  
    }
}
Unhandled exception. System.Text.Json.JsonException: The JSON value could not be converted to System.Byte[]. Path: $.ByteArray | LineNumber: 0 | BytePositionInLine: 16.
 ---> System.InvalidOperationException: Cannot get the value of a token type 'StartArray' as a string.
   at System.Text.Json.Utf8JsonReader.TryGetBytesFromBase64(Byte[]& value)
   at System.Text.Json.Utf8JsonReader.GetBytesFromBase64()
   at System.Text.Json.Serialization.Converters.JsonConverterByteArray.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
   at System.Text.Json.JsonPropertyInfoNotNullable`4.OnRead(ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.JsonPropertyInfo.Read(JsonTokenType tokenType, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& readStack, Utf8JsonReader& reader, Exception ex)
   at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
   at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader)
   at System.Text.Json.JsonSerializer.Deserialize(String json, Type returnType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
   at Program.Main()
Command terminated by signal 6

Solution

  • With Sytem.Text.Json a byte array (byte[]) will be serialized as base64 string. They stated that they won't add support for byte[] to be serialized as number array in a github issue.

    Here's a custom converter that should get you started. Maybe you could optimize the reading a bit but the performance hit taken by this approach shouldn't be too bad. You might want to add null and error handling but you get the idea.

    To apply the custom converter, you'll have to add them to the JsonSerializerOptions. Please refer to this docs page for that.

    public class ByteArrayConverter : JsonConverter<byte[]>
    {
        public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            short[] sByteArray = JsonSerializer.Deserialize<short[]>(ref reader);
            byte[] value = new byte[sByteArray.Length];
            for (int i = 0; i < sByteArray.Length; i++)
            {
                value[i] = (byte)sByteArray[i];
            }
    
            return value;
        }
    
        public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
        {
            writer.WriteStartArray();
    
            foreach (var val in value)
            {
                writer.WriteNumberValue(val);
            }
    
            writer.WriteEndArray();
        }
    }