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
抛出异常:
发生了'System.InvalidOperationException'类型的异常 protobuf-net.dll但未在用户代码中处理
附加信息:预计不会输入类型,也不能签订合同 推断:MyNamespace.MyType
显然protobuf-net
期望使用proto contract属性修饰类声明:
[Serializable]
[ProtoBuf.ProtoContract(Name=@"MyTypeProto")]
public partial class MyType: ProtoBuf.IExtensible
{
但是,由于我使用DateTime
和int?
等类型,因此我不相信我可以创建兼容的proto2
消息类型。
如何构建我的类以便protobuf-net
可以成功序列化?
UPDATE :如果我添加[Protobuf.ProtoContract]
属性,那么我可以序列化/反序列化,不会抛出任何异常,但我的反序列化对象已丢失所有值(所有字段都为空):
[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
答案 0 :(得分:1)
所有它要求你告诉它你的类型真的是用于protobuf序列化;这样:
[ProtoBuf.ProtoContract]
public partial class MyType ...
该名称完全是可选的。实际上,protobuf-net的大多数使用都是代码优先的,而不是架构优先的(甚至是架构式的),所以我会打赌它是不寻常的来拥有一个明确的名字。
作为旁注,但是; DateTime
和int?
都可以在.proto
中表达(尽管int?
比DateTime
更清晰 - 它只是optional
字段,如果您选择从类型模型生成架构,而您不需要这样做。)
它不承认[Serializable]
,因为这意味着完全不同的东西,甚至不能在所有平台上使用。