将Newtonsoft JSON序列化为字节数组

时间:2018-10-04 15:27:19

标签: c# json.net

我的目标是在字节数组字段中发送包含标头对象和压缩数据的JSON。

[JsonObject(MemberSerialization.OptOut)]
public class Message
{
    public Message()
    {
        Header = new Header();
    }

    public Header Header { get; set; }


    public byte[] Data { get; set; }
}

字节数组是gzip压缩的JSON对象,但这无关紧要。我遇到的问题是,如果我将JSON序列化,它将转换为字符串,然后转换回字节。问题是,消息的大小增加了很多,因为序列化字节数组会将其转换为字符串表示形式。

我受到最大消息大小的束缚,并且已经将压缩数据吐出,但是当我发送以Byte数组和Uncompressed标头形式发送包含压缩数据的JSON时,序列化JSON对象使我超出了消息大小限制。

有没有可靠的方法可以立即将JSON对象转换为字节数组。

           var stringMessage = JsonConvert.SerializeObject(message,Formatting.None);
            var bytes = Encoding.UTF8.GetBytes(stringMessage);

            var stringMessage2 = JsonConvert.SerializeObject(message.TransportHeader, Formatting.None);
            var bytes2 = Encoding.UTF8.GetBytes(stringMessage2);

            Message eventMessage = new Message(bytes);
            var bytes3= Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message.Transportdata));

压缩数据大小= 243905

序列化后的完整JSON(以字节为单位)= 325313

仅标头(字节大小为90)

仅压缩数据序列化并转换回字节= 325210,(当数据通过JsonConvert.SerializeObject序列化并生成字符串表示形式时,大小会增加)

它显然上升了很多,这是由字节数组引起的。

2 个答案:

答案 0 :(得分:2)

JSON是基于字符的格式,因此必然涉及字符数据。我怀疑您使用了UTF16编码,该编码将每个字符分成两个字节。如果您使用UTF8,则不会遇到任何有意义的大小开销。

答案 1 :(得分:2)

我找到了一种实现所需功能的方法,它不完全是JSON,而是BSON或也称为Binary JSON。好吧,既然找到解决方案纯粹是个运气,所以我不确定BSON的知名度。

无论如何,Newtonsoft都通过https://www.nuget.org/packages/Newtonsoft.Json.Bson/1.0.1

上的Newtonsoft.Json.Bson nuget包来支持它。

一些用于序列化/反序列化的代码

            foreach (var message in transportMessageList)
        {
            MemoryStream ms = new MemoryStream();
            using (BsonDataWriter writer = new BsonDataWriter(ms))
            {
                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(writer, message);
            }

            var bsonByteArray = ms.ToArray();
            Assert.True(bsonByteArray.Length!=0);
            bsonList.Add(bsonByteArray);
        }

        var deserializdTransmortMessageList = new List<TransportMessage>();
        foreach (var byteArray in bsonList)
        {
            TransportMessage message;
            MemoryStream ms = new MemoryStream(byteArray);
            using (BsonDataReader reader = new BsonDataReader(ms))
            {
                JsonSerializer serializer = new JsonSerializer();
                message = serializer.Deserialize<TransportMessage>(reader);
            }
            Assert.True(message.Transportdata.Length!=0);
            deserializdTransmortMessageList.Add(message);
        }

您可以使用与JSON相同的类/对象,序列化压缩的字节数组不再导致大小增加。

请注意,Newtonsoft网站上的BSON文档已过时,此时仅列出不推荐使用的api调用。我的代码使用正确的不建议使用的API调用。