2014-02-15 83 views
0

爲我目前的項目我正在與protobuf網,我得到了一些奇怪的結果。
我有一個包含兩個屬性的類:Protobuf-net序列化

[ProtoContract] 
class MyClass{ 
    [ProtoMember(1)] 
    public int ID { get; set; } 
    [ProtoMember(2)] 
    public string Description { get; set; } 
} 

如果我設置ID爲0,並輸入一個隨機Description和檢查序列化byte[]後來,我沒有得到預期的結果。

我想用長度前綴序列化類。

我序列化類是這樣的:

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

我期待這樣的事情:

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 

相反,我得到: 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

什麼是0x12開頭? 0x00!= 0x12? 我認爲我已經做了正確的事,但是在我的代碼中可能存在一個愚蠢的錯誤?

回答

2

十六進制12是字段標題,並且是二進制10010.最後3位(010)是導線類型:長度前綴。餘數(10)是字段編號(2)。所以十六進制數12表示後面是字段2,長度前綴(在這種情況下,是一個字符串)。由於protobuf-net的隱式零默認行爲,字段1被省略。如果需要,您可以強制字段1以多種方式序列化。

0

以下是顯示如何序列化的示例代碼。

它包括使用ProtoBuf序列化和反序列化任何類的擴展方法。

要使用,請包括NuGet包protobuf-net(我使用的版本爲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; } 
}