【问题标题】:The JSON value could not be converted to System.Byte[]JSON 值无法转换为 System.Byte[]
【发布时间】:2020-05-02 20:34:20
【问题描述】:

在处理字节数组时尝试反序列化以下 JSON 时出现以下异常,这是怎么回事?

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

【问题讨论】:

  • 很奇怪,它适用于int[]。这可能是序列化程序中的限制或错误。你搜索过github repo吗?
  • 我已经创建了示例JsonRoot 对象var test = new JsonRoot { ByteArray = new[] { (byte)1 } }; 并将其序列化以进行测试,并得到{"ByteArray":"AQ=="} 结果。看来,System.Text.Json 在底层使用了字节数组的特殊规则。可能是因为它使用了Utf8JsonReader/Utf8JsonWriter
  • 我的第一条评论是对的。我添加了一个带有链接的答案。当我有时间时,我会添加一个自定义转换器来满足您的需求。
  • 我四处搜索,但找不到与此相关的任何问题。
  • @KevinSmith 添加了转换器。您可能希望对其进行一些扩展以更好地处理 null 和错误,但这应该可以帮助您入门。

标签: c# system.text.json


【解决方案1】:

使用Sytem.Text.Json 字节数组 (byte[]) 将被序列化为 base64 字符串。他们表示不会添加对 byte[] 的支持,以将其序列化为 github issue 中的数字数组。

这是一个可以帮助您入门的自定义转换器。也许您可以稍微优化一下读数,但这种方法对性能的影响应该不会太差。您可能想要添加 null 和错误处理,但您明白了。

要应用自定义转换器,您必须将它们添加到 JsonSerializerOptions。请参考this docs page

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

【讨论】:

  • 谢谢,很棒的答案 - 不知道它只有 base64!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2019-12-28
  • 1970-01-01
相关资源
最近更新 更多