简体   繁体   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#

I'm not using protogen.exe to generate my classes from message-type defs我没有使用protogen.exe从消息类型 defs 生成我的类

Because I have additional requirements, I wrote my own generator which writes classes such as :因为我有额外的要求,我编写了自己的生成器,它编写了如下类:

[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;

But when I attempt to serialize :但是当我尝试序列化时:

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

protobuf-net throws exception : protobuf-net抛出异常:

An exception of type 'System.InvalidOperationException' occurred in protobuf-net.dll but was not handled in user code protobuf-net.dll 中发生“System.InvalidOperationException”类型的异常,但未在用户代码中处理

Additional information: Type is not expected, and no contract can be inferred: MyNamespace.MyType附加信息:类型不是预期的,并且不能推断出合同:MyNamespace.MyType

Apparently protobuf-net is expecting the class declaration to be decorated with a proto contract attribute :显然protobuf-net期望用 proto 合同属性装饰类声明:

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

However since I'm using types such as DateTime and int?但是,由于我使用的是DateTimeint?等类型int? I don't believe it's possible for me to create a compatible proto2 message-type.我不相信我可以创建兼容的proto2消息类型。

How to structure my classes so that protobuf-net can successfully serialize ?如何构建我的类以便protobuf-net可以成功序列化?

UPDATE : If I add the [Protobuf.ProtoContract] attribute then I can serialize/deserialize with no exceptions thrown, but my deserialized object has lost all values ( all fields are null ) :更新:如果我添加[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

All it is asking for is for you to tell it that your type really is intended for protobuf serialization;它所要求的只是让您告诉它您的类型确实是用于 protobuf 序列化的; so:所以:

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

The name is entirely optional.该名称完全是可选的。 Indeed, most uses of protobuf-net are code-first rather than schema-first (or even schema-ever), so I would wager that it is unusual to have an explicit name.事实上,protobuf-net 的大多数用途都是代码优先而不是模式优先(甚至是模式永远),所以我敢打赌,有一个明确的名字是不寻常的

As a side note, though;不过,作为旁注; DateTime and int? DateTimeint? can both be expressed in .proto (although the int? is a lot cleaner than the DateTime - it just becomes an optional field, if you choose to generate the schema from the type model, which you don't need to).两者都可以用.proto表示(尽管int?DateTime更清晰——它只是成为一个optional字段,如果您选择从类型模型生成架构,您不需要这样做)。

It doesn't acknowledge [Serializable] because that means something quite different and isn't even available on all platforms.它不承认[Serializable]因为这意味着完全不同的东西,甚至不是在所有平台上都可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM