ProtoBuf.Net - 使用 Proto 作为 TypeFormatter

Posted

技术标签:

【中文标题】ProtoBuf.Net - 使用 Proto 作为 TypeFormatter【英文标题】:ProtoBuf.Net - Use Proto as TypeFormatter 【发布时间】:2012-03-25 15:41:18 【问题描述】:

我使用 ProtoBuf.Net 作为 NetDataContractSerializer(或 BinarySerializer)进行 POC, 我已经在这里code 发布了代码。 这是反复试验,但仍然不适用于 List、Dictionary 等。 看来我走错方向了 可行吗?

您的反馈将不胜感激。

【问题讨论】:

是不是预先知道了完整的候选根类型?还是您打算序列化完全未知的类型? 提前知道,类型在序列化和反序列化两边都知道 【参考方案1】:

我正在使用 Protobuf.net,我通过这样标记我的类来做到这一点:

  namespace music
  
      [ProtoContract]
      public class Album
      
          [ProtoMember(1)]
          public string Name  get; set; 

          [ProtoMember(2)]
         public List<string> TrackList  get; set; 
      
  

这也适用于字典和列表。

与使用 .proto 消息文件的属性相同的编号约定适用于属性,但您可以像这样在基类中包含属性:

[ProtoContract]
[ProtoInclude(10, typeof(TypeInheritingFromPerson))]
[ProtoInclude(11, typeof(AnotherTypeInheritingFromPerson))]
public abstract class Person

    [DataMember]
    [ProtoMember(1)]
    public string Name  get; set; 
 ...

然后使用这行代码进行序列化:

  MemoryStream stream = new MemoryStream();
  ProtoBuf.Serializer.Serialize<Album>(stream, album);

你当然可以使用文件流而不是内存流:)

如果您使用 WCF,您可以像这样直接在配置文件中将 DataContractSerializer 替换为 Protobuf 序列化程序(从 protobuf.net 文档中复制粘贴),因此您无需手动调用任何序列化代码:

将以下内容添加到服务器和客户端 app.config 的 system.serviceModel 部分:

           <behaviors>
           <endpointBehaviors>
             <behavior name="ProtoBufBehaviorConfig">
               <ProtoBufSerialization/>
             </behavior>
           </endpointBehaviors>
         </behaviors>
         <extensions>
           <behaviorExtensions>
             <add name="ProtoBufSerialization" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=1.0.0.255, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
           </behaviorExtensions>
         </extensions>

将您的端点配置为具有如下行为配置:

         <service name="TK.Framework.Samples.ServiceModel.Contract.SampleService">
           <endpoint address="http://myhost:9003/SampleService" binding="basicHttpBinding" behaviorConfiguration="ProtoBufBehaviorConfig"
            bindingConfiguration="basicHttpBindingConfig" name="basicHttpProtoBuf" contract="ISampleServiceContract" />
         </service>
         <client>
             <endpoint address="http://myhost:9003/SampleService" binding="basicHttpBinding"
                 bindingConfiguration="basicHttpBindingConfig" contract="ISampleServiceContract"
                 name="BasicHttpProtoBufEndpoint" behaviorConfiguration="ProtoBufBehaviorConfig"/>
          </client>

我希望这对您有所帮助,但如果您有任何问题或不清楚的地方,请告诉我:)

【讨论】:

感谢您的回复,我正在使用 Protobuf.NetV2 并使用运行时注册(附加代码)。我可能遗漏了一些东西,因为我对所有成员及其成员进行递归以在其中注册所有需要的对象图。当添加 List 或 Dictionary 时,我无法序列化作为 List/Dictionary 成员的锯齿状/嵌套数组。我想我错过了 Protobuf 用来序列化 List/Dictionary 的内容,因为显然它的成员没有用 Proto Attributes 标记。 你的数据/类结构是什么样的?您是否使用了无法用 protobuf 属性装饰的类型? 嗯...您是否查看过 ProtoBuf.Meta 命名空间中可用的内容? 我可以用属性装饰我的类型,但我不情愿,因为我想保持我的域实体清洁序列化属性(可序列化除外)。V2 允许在运行时将它们添加到模态,所以我想行为与装饰方法是对称的。我使用了这个命名空间,正如您在链接代码中看到的那样,您是否特别指的是某些功能? 我想知道这是否与在字典中包含列表的复杂性有关,所以我做了一个小样本来测试它(使用类上的 protobuf 属性)。瞧,我在另一边也看到了 null :\ 我想这是有道理的,因为没有足够的关于列表的信息来创建 .proto 消息。我现在也在 PoCing 这个,所以如果我找到解决方法,我会发布它:)

以上是关于ProtoBuf.Net - 使用 Proto 作为 TypeFormatter的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net - 啥被序列化了?

ProtoBuf 在反序列化期间损坏字节数组(添加了额外的 0)

Protobuf.net 内存使用情况

使用 protobuf.net 序列化图形时出现问题

使用 DataContract 属性时 ProtoBuf.NET 未序列化

Protobuf.net 异常 - 检查元数据时超时