簡體   English   中英

protobuf-net 序列化所需的已定義 proto2 消息類型?

[英]defined proto2 message-type necessary for protobuf-net serialization?

protobuf-net v2.1.0 ( latest available as NuGet package ) 
Visual Studio 2015 v14 
C#

我沒有使用protogen.exe從消息類型 defs 生成我的類

因為我有額外的要求,我編寫了自己的生成器,它編寫了如下類:

[Serializable]  
public partial class MyType: ProtoBuf.IExtensible                                   
{                                                                                               
  [ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"RegistrationDate", DataFormat = ProtoBuf.DataFormat.Default)]
  [System.ComponentModel.DefaultValue("1/1/0001 12:00:00 AM")]                                                          
  public DateTime RegistrationDate;                                                                         

  [ProtoBuf.ProtoMember(2, IsRequired = false, Name = @"RegistrationId", DataFormat = ProtoBuf.DataFormat.TwosComplement)]
  [System.ComponentModel.DefaultValue(null)]                                            
  public long? RegistrationId;

但是當我嘗試序列化時:

var  myObject = new MyType(RegistrationDate="2016-01-01",RegistrationId=1);
var stream = new MemoryStream();
ProtoBuf.Serializer.Serialize(stream, myObject );

protobuf-net拋出異常:

protobuf-net.dll 中發生“System.InvalidOperationException”類型的異常,但未在用戶代碼中處理

附加信息:類型不是預期的,並且不能推斷出合同:MyNamespace.MyType

顯然protobuf-net期望用 proto 合同屬性裝飾類聲明:

[Serializable]
[ProtoBuf.ProtoContract(Name=@"MyTypeProto")]   
public partial class MyType: ProtoBuf.IExtensible                                   
{

但是,由於我使用的是DateTimeint?等類型int? 我不相信我可以創建兼容的proto2消息類型。

如何構建我的類以便protobuf-net可以成功序列化?

更新:如果我添加[Protobuf.ProtoContract]屬性,那么我可以序列化/反序列化而不拋出異常,但是我的反序列化對象丟失了所有值(所有字段都為 null ):

[Serializable]  
[Protobuf.ProtoContract]
public partial class MyType: ProtoBuf.IExtensible                                   
{                                                                                               
  [ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"RegistrationDate", DataFormat = ProtoBuf.DataFormat.Default)]
  [System.ComponentModel.DefaultValue("1/1/0001 12:00:00 AM")]                                                          
  public DateTime RegistrationDate;                                                                         

  [ProtoBuf.ProtoMember(2, IsRequired = false, Name = @"RegistrationId", DataFormat = ProtoBuf.DataFormat.TwosComplement)]
  [System.ComponentModel.DefaultValue(null)]                                            
  public long? RegistrationId;

  var  myObject = new MyType(RegistrationDate="2016-01-01",RegistrationId=1);
  var stream = new MemoryStream();
  ProtoBuf.Serializer.Serialize(stream, myObject );
  var deserialized = ProtoBuf.Serializer.Deserialize<MyType>(stream);
  // deserialized.RegistrationDate is null
  // deserialized.RegistrationId is null

它所要求的只是讓您告訴它您的類型確實是用於 protobuf 序列化的; 所以:

[ProtoBuf.ProtoContract]   
public partial class MyType ...

該名稱完全是可選的。 事實上,protobuf-net 的大多數用途都是代碼優先而不是模式優先(甚至是模式永遠),所以我敢打賭,有一個明確的名字是不尋常的

不過,作為旁注; DateTimeint? 兩者都可以用.proto表示(盡管int?DateTime更清晰——它只是成為一個optional字段,如果您選擇從類型模型生成架構,您不需要這樣做)。

它不承認[Serializable]因為這意味着完全不同的東西,甚至不是在所有平台上都可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM