如何描述 protobuf-net 中的 Any 类型?

Posted

技术标签:

【中文标题】如何描述 protobuf-net 中的 Any 类型?【英文标题】:How can I describe the Any type in protobuf-net? 【发布时间】:2016-01-06 16:29:44 【问题描述】:

在 google protobuf v3 中有 Any 类型,允许您序列化标识消息的名称/url(https://developers.google.com/protocol-buffers/docs/proto3#any、https://github.com/google/protobuf/blob/master/src/google/protobuf/any.proto)。

是否可以描述这个结构并让 protobuf-net 序列化/反序列化它?我需要它遵循 protobuf v3 标准,所以 DynamicType/bcl.NetObjectProxy 很接近,但不兼容二进制。

如果不是,那么使用 protobuf-net 使用 Any 构造序列化对象的最佳方法是什么?我真的不想切换到 protobuf-csharp 版本。

【问题讨论】:

仅供参考,我目前正在积极致力于 proto3 支持和工具更新;我希望在 2.3.0 版本中看到完整的 Any 支持。 【参考方案1】:

最终,Any 可以被视为:

[ProtoContract]
public sealed class Any 
    [ProtoMember(1)] public string type_url get;set;
    [ProtoMember(2)] public byte[] value get;set;

从那里,您可以对 url 执行 switch(或字典查找),将值加载到 MemoryStream,然后回调到 protobuf-net。对于序列化,类型 url 可能会存储在针对类型的属性中,但这是更棘手的雾反序列化。也许是一个字符串到类型的字典和非泛型 API。

【讨论】:

顺便说一句,我很乐意考虑使用辅助方法等将Any 添加到库中,但我有兴趣查看用于从名称解析类型的正确 API。展开并不是一件简单的事情,尤其是在反序列化期间(序列化非常简单) 是的,我想过。但我希望 protobuf-net 对字节进行(反)序列化。我在 protobuf-net 中真正想要的是能够用 ITypeFormatter.[De]Serialize(Proto[Reader/Writer], object) 之类的东西覆盖(反)序列化。它可以通过 Json.net JsonConverterAttribute 等属性选择和/或动态添加到覆盖默认值的模型中。然后用户可以 100% 控制输入/输出,本地实现 [ProtoAny()] 等作为特定序列化程序的快捷方式。 只是为了设置场景,最终目标是用 protobuf/json 替换专有的二进制序列化程序,用于 asp.net 5 Web Api Websocket RPC。 Any 的使用是为了能够使用“插件”动态扩展 WebSocket API 表面。 Websocket Text/Bin 模式将在 Json/Protobuf 序列化器之间进行选择。因此,我还将进行“protobuf canonical json”序列化,并在这些东西上使用 GetProto() 来为其他不使用 C# 的用户获取正确的 .proto 文件。但我更喜欢“代码优先”而不是 .proto 优先,因为很难从通用 .proto 文件中获得好的代码。 @maloo 问题:您需要支持其他(非 protobuf-net)库吗?因为:protobuf-net 很久以前就实现了您所描述的内容...AsDynamic,IIRC(不记得是在合同上,在成员上还是在两者上)。但是,它的实现方式不同,并且与Any 不直接兼容 其他 protobuf 库?如果是这样,没有。除非我当然不能让 GetProto 生成 Any 合同,但保留 System.Object 或类似的成员类型。听起来这需要在 protobuf-net 上做一些工作。所以我可能只使用来自模型类型的简单 protobuf 读取器/写入器 + T4 代码 + proto gen。这就是我为旧东西所做的,并且非常灵活、快速,但当然要编写和维护更多代码。

以上是关于如何描述 protobuf-net 中的 Any 类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 RuntimeTypeModel 将 ProtoInclude 与 protobuf-net 中的类型相关联?

使用protobuf-net继承时如何选择字段号?

如何使用 protobuf-net 读回附加的对象?

Protobuf-Net:如何序列化 guid?

C# Protobuf-net:如何从网络流中连续反序列化?

如何在 Protobuf-net 中动态添加 Proto 成员