Я использую ProtoBuf.NET для сериализации/десериализации некоторых классов. Я нахожу, что при десериализации я получаю поврежденный байт [] (дополнительные 0). Прежде чем спросить, да, мне нужно * WithLengthPrefix() версии АФИ Protobuf поскольку часть Protobuf находится в началах пользовательского потока :)ProtoBuf искажает массив байтов во время десериализации (добавлено 0 добавлено)
Во всяком случае, я вижу
Original object is (JSON depiction):
{"ByteArray":"M+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcfxcWA==","K":2,"V
":1.0}
Protobuf: Raw Hex (42 bytes):
29-2A-20-0A-0C-33-E0-7A-AB-E3-D7-36-E1-7C-3F-98-65-12-10-0E-61-2B-C5-54-36-CB-CE
-C8-CA-94-91-71-FC-5C-58-08-02-15-00-00-80-3F
Regenerated object is (JSON depiction):
{"ByteArray":"AAAAAAAAAAAAAAAAM+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcf
xcWA==","K":2,"V":1.0}
дополнительные AAA*A
в элементе ByteArray
являются в основном шестнадцатеричными 0x00 в base64.
Логика приложения похожа на
static void Main(string[] args)
{
var parent = new Parent();
parent.Init();
Console.WriteLine("\nOriginal object is (JSON depiction):");
Console.WriteLine(JsonConvert.SerializeObject(parent));
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, parent, PrefixStyle.Base128);
byte[] bytes2 = ms.ToArray();
var hex2 = BitConverter.ToString(bytes2);
Console.WriteLine("\nProtobuf: Hex ({0} bytes):\n{1}", bytes2.Length, hex2);
ms.Seek(0, SeekOrigin.Begin);
var backFirst = Serializer.DeserializeWithLengthPrefix<Parent>(ms,PrefixStyle.Base128);
Console.WriteLine("\nRegenerated object is (JSON depiction):");
Console.WriteLine(JsonConvert.SerializeObject(backFirst));
}
}
Классы DTO являются
[DataContract]
[ProtoContract]
internal class Parent : Child
{
[DataMember(Name = "ByteArray", Order = 10)]
[ProtoMember(1)]
public byte[] ByteArray { get; set; }
[DataMember(Name = "ByteArray2", Order = 30, EmitDefaultValue = false)]
[ProtoMember(2)]
public byte[] ByteArray2 { get; set; }
public Parent()
{
ByteArray = new byte[12];
}
internal void Init(bool bindRow = false)
{
base.Init();
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(ByteArray);
ByteArray2 = new byte[16];
rng.GetBytes(ByteArray2);
}
}
[DataContract]
[ProtoContract]
[ProtoInclude(5, typeof(Parent))]
public class Child
{
[DataMember(Name = "K", Order = 100)]
[ProtoMember(1)]
public Int32 K { get; set; }
[DataMember(Name = "V", Order = 110)]
[ProtoMember(2)]
public float V { get; set; }
internal void Init()
{
K = 2;
V = 1.0f;
}
}
Я вижу, что, когда я перехожу ByteArray = new byte[12]
из образуют Parent
конструктор в это Init()
метод, Protobuf работает отлично. Однако у нас есть логика приложения, которая предотвращает это в реальной версии (по сравнению с тем, который вы видите выше).
Мы делаем что-то неправильно или это ошибка в ProtoBuf?
Инициализация довольно похожа, я имел в виду, что использование этого класса другими классами таково, что я не могу слишком сильно изменить подпрограммы ctor/init (по крайней мере, не без значительного рефакторинга). Thx для ответа, я скоро проверю его. – DeepSpace101
@Sid и ни одна из показанных вещей не связана с изменением подпрограмм ctor/init –