如何将byte []序列化为简单的JSON数组而不是JSON.net中的base64?

Mar*_*cus 27 javascript serialization bytearray json.net

我使用JSON.net来序列化C#和JavaScript之间的一些对象.JSON数据通过WebSocket在.NET和浏览器应用程序之间传输.

在数据结构中有一些byte[]字段,我也希望这些字段Array在JavaScript中.

如何将C#序列化为byte[]简单的JSON数组[ 0 , 1 , 254, 255 ]而不是base64字符串?

Pau*_*ner 55

JSON.NET选择BinaryConverter读取和写入字节数组.您可以在源代码中看到它使用具有字节数组WriteValueJsonWriter类上的操作,这使得它们被写为Base-64.

要修改它,您可以编写自己的转换器,以您期望的格式读取和写入数组:

public class ByteArrayConverter : JsonConverter
{
    public override void WriteJson(
        JsonWriter writer,
        object value,
        JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        byte[] data = (byte[])value;

        // Compose an array.
        writer.WriteStartArray();

        for (var i = 0; i < data.Length; i++)
        {
            writer.WriteValue(data[i]);
        }

        writer.WriteEndArray();
    }

    public override object ReadJson(
        JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            var byteList = new List<byte>();

            while (reader.Read())
            {
                switch (reader.TokenType)
                {
                    case JsonToken.Integer:
                        byteList.Add(Convert.ToByte(reader.Value));
                        break;
                    case JsonToken.EndArray:
                        return byteList.ToArray();
                    case JsonToken.Comment:
                        // skip
                        break;
                    default:
                        throw new Exception(
                        string.Format(
                            "Unexpected token when reading bytes: {0}",
                            reader.TokenType));
                }
            }

            throw new Exception("Unexpected end when reading bytes.");
        }
        else
        {
            throw new Exception(
                string.Format(
                    "Unexpected token parsing binary. "
                    + "Expected StartArray, got {0}.",
                    reader.TokenType));
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(byte[]);
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以通过应用JsonConverterAttribute成员来使用它:

[JsonConverter(typeof(ByteArrayConverter))]
public byte[] Data { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 提供实际 ByteArrayConverter 类的奖励积分!但是,有一个小错误。因为你已经在使用 JsonWriter,所以不需要手动添加逗号,所以你可以删除这部分: if(i != data.Length) { writer.WriteRaw(","); 否则你的数组将如下所示:[12,,54,,32,,8] (2认同)

Joe*_*nos 14

我能想到的最简单的方法是将字节数组转换为整数数组,如:

var intArray = byteArray.Select(b => (int)b).ToArray();
Run Code Online (Sandbox Code Playgroud)

这不需要对JSON库或任何自定义序列化或类似的任何特殊处理.

编辑:这意味着必须自定义您的数据对象来处理不同的类型.也许:

public class CustomFoo : Foo
{
    // SomeBytesHere is a byte[] in the base class
    public new int[] SomeBytesHere { get;set; }
}
Run Code Online (Sandbox Code Playgroud)

所以也许它不是最简单的 - 取决于你需要序列化多少东西