使用知道架构的 protobuf-net 反序列化未知对象

Posted

技术标签:

【中文标题】使用知道架构的 protobuf-net 反序列化未知对象【英文标题】:Deserialize unknown object with protobuf-net knowing the schema 【发布时间】:2021-04-21 12:16:38 【问题描述】:

我必须解析返回的未知类型的消息,由 protobuf-net 序列化。

我已经成功地从原始字节中解析回 FileDescriptorSet,我的意思是我知道类型名称,它的字段等。但是如何在不知道它的类型的情况下反序列化消息? This question 和 Marc 的回答很接近,但我不明白如何使用 Extensible 类。

你可能需要创建一个非抽象类来玩,但是类 Foo : Extensible 应该足够了,然后 Serializer.Deserialize(source).

所以我没有“Foo”,我只有 FileDescriptorSet 和序列化的消息字节。我需要在“即时”代码中完成。如何将 FileDescriptorSet 与字节数组结合,包含未知消息类型的值?

【问题讨论】:

【参考方案1】:

这个问题没有简单的答案,而且我还不需要完全实现一个例子。 Extensible 在这里为我们做的唯一事情是允许对仍以字节形式存储的临时字段进行基本访问。因此:您可以从数据源中反序列化 Extensible,然后使用 Extensible.GetValue<Type>(obj, fieldNumber) 和该 API 的相关重载。您需要根据您对正在查看的DescriptorProto自己 解释来执行此操作(DescriptorProtoFileDescriptorSet 中的一种类型)。例如,您可以枚举.Fields,并且对于每个:从.type.TypeName 推断出一些<T>(您必须将其解析为另一个DescriptorProtoEnumDescriptorProto 等),以及@ 987654333@(用于标签)。对于任何消息类型,您都可以再次使用Extensible 并递归地重复该过程。您还需要检查 .Label 以查看是否重复,如果重复:请改用 Extensible.GetValues<T>

这就是理论。我没有必要付诸实践。

【讨论】:

除了反序列化可扩展之外,我几乎了解所有内容。如果我尝试使用 Serializer.Deserialize(input_message_bytes) ;它给了我一个异常“类型不是预期的,并且不能推断出任何合同:”。要使用 GetValue 方法,我必须以某种方式获取 Extensible 实例。 @Michael [ProtoContract] public sealed class UseThisInstead : Extensible

以上是关于使用知道架构的 protobuf-net 反序列化未知对象的主要内容,如果未能解决你的问题,请参考以下文章

protobuf-net:不正确的线型反序列化 TimeSpan

Protobuf-net 对字节数组进行序列化/反序列化

使用 protobuf-net,是不是可以在不分配内存的情况下反序列化消息?

使用 protobuf-net 反序列化不同的列表

使用 protobuf-net 反序列化字典

为啥我不能使用 ProtoBuf-Net 正确反序列化我的对象?