简体   繁体   中英

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

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();
    }
}

Using ASP.NET 6:

In your model:

public class JsonRoot
{
    // Add this attribute to your byte array(s).
    [JsonConverter(typeof(JsonToByteArrayConverter))]
    public byte[] ByteArray {get;set;}  
}

Add a new class:

using System.Text.Json;
using System.Text.Json.Serialization;

internal sealed class JsonToByteArrayConverter : JsonConverter<byte[]?>
{
    // Converts base64 encoded string to byte[].
    public override byte[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (!reader.TryGetBytesFromBase64(out byte[]? result) || result == default)
        {
            throw new Exception("Add your fancy exception message here...");
        }
        return result;
    }

    // Converts byte[] to base64 encoded string.
    public override void Write(Utf8JsonWriter writer, byte[]? value, JsonSerializerOptions options)
    {
        writer.WriteBase64StringValue(value);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM