Hex 12 is the field header, and is binary 10010. The last 3 bits (010) is the wire type: length-prefixed. The remainder (10) is the field number (2). So the hex 12 is indicating that what follows is field 2, length-prefixed (in this case, a string). Field 1 has been omitted due to protobuf-net's implicit zero default behavior. You can force field 1 to be serialized in a number of ways if you need to.
Protobuf-net serialization
-
12-10-2022 - |
Вопрос
for my current project I'm working with protobuf-net and I got some weird results.
I have a class that contains two properties:
[ProtoContract]
class MyClass{
[ProtoMember(1)]
public int ID { get; set; }
[ProtoMember(2)]
public string Description { get; set; }
}
If I set ID
to 0 and enter a random Description
and check the serialized byte[]
afterwards, I don't get the expected result.
I would like to serialize the class with a length prefix.
I'm serializing the class like this:
var myclass = new MyClass()
{
ID = 0, Description = "ThisIsAShortDescription"
};
using(var stream = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix<MyClass>(stream, myclass, PrefixStyle.Base128);
Console.WriteLine(BitConverter.ToString(stream.GetBuffer());
}
I'm expecting something like this:
19 00 17 54 68 69 73 49 73 41 53 68 6f 72 74 44 65 73 63 72 69 70 74 69 6f 6e
19 -> length of the packet
00 -> ID
17 -> length of following string
rest -> string
Instead I'm getting: 19 12 17 54 68 69 73 49 73 41 53 68 6f 72 74 44 65 73 63 72 69 70 74 69 6f 6e
What is this 0x12 at the beginning? 0x00 != 0x12? I think that I've done anything right but is there maybe a silly bug in my code?
Решение
Другие советы
Here is sample code showing how to serialize.
It includes extension methods to serialize and deserialize any class using ProtoBuf
.
To use, include the NuGet package protobuf-net
(I used version 2.0.0.668
).
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ProtoBuf;
namespace Protobuf_Net
{
class Program
{
static void Main(string[] args)
{
MyMessage original = new MyMessage(42, "Bob");
byte[] rawBytes = original.ProtoBufSerialize<MyMessage>();
MyMessage deserialized = rawBytes.ProtoBufDeserialize<MyMessage>();
Console.WriteLine("Num={0}", deserialized.Num);
Console.WriteLine("Name={0}", deserialized.Name);
Console.Write("[any key]");
Console.ReadKey();
}
}
}
public static class ProtoBufExtensions
{
// Intent: serializes any class to a byte[] array.
public static byte[] ProtoBufSerialize<T>(this T message)
{
byte[] result;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, message);
result = stream.ToArray();
}
return result;
}
// Intent: deserializes any class from a byte[] array.
public static T ProtoBufDeserialize<T>(this byte[] bytes)
{
T result;
using (var stream = new MemoryStream(bytes))
{
result = Serializer.Deserialize<T>(stream);
}
return result;
}
}
[ProtoContract]
public struct MyMessage
{
public MyMessage(int num, string name)
{
Num = num;
Name = name;
}
[ProtoMember(1)]
public int Num { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
}