带有未知子类的 Protobuf-net 异常
Posted
技术标签:
【中文标题】带有未知子类的 Protobuf-net 异常【英文标题】:Protobuf-net Exception with Unknown Subclasses 【发布时间】:2011-08-27 23:50:42 【问题描述】:我开发了一个应用程序,旨在使用序列化对象将数据从客户端发送到服务器并返回等。
对于这个应用程序,我认为 protobuf-net 将是一个不错的选择(尤其是因为它可以很好地处理可变长度对象)。
但是,当从客户端向服务器发送对象或反之亦然时,我只知道该对象将是“ReplicableObject”的某个子类。因此,我正在使用:
Serializer.SerializeWithLengthPrefix(stream, ro, PrefixStyle.Base128);
其中 'ro' 是从 ReplicableObject 子类化的类型的对象。
但是,我得到了这个例外:
“ProtoBuf.ProtoException”类型的未处理异常发生在 protobuf-net.dll
附加信息:序列化过程中发现意外类型; 类型必须包含在 ProtoIncludeAttribute 中;找到 MessageObject 作为 ReplicableObject 传递
在这个特定的实例中,我正在尝试发送一个 MessageObject。
由于 protobuf-net 的文档很少,所以我不知道该怎么做。我在这里和那里尝试了一些属性,但无济于事。
任何帮助表示赞赏。
编辑:我应该明确指出,子类甚至可能不是我写的。
【问题讨论】:
我刚从几天外回来。我稍后会看这个 【参考方案1】:Protobuf 是一种基于契约的序列化格式,旨在独立于平台。因此,no 类型的元数据包含在线路上,因为它不适用于平台之间。甚至继承也不是核心 protobuf 规范的一部分。
protobuf-net 作为一个特定的实现引入了对继承的支持(通过一些烟雾和镜子),但理想情况下它应该仍然可以提前定义预期的类型 - 与其他序列化程序完全相同例如XmlSerializer
或DataContractSerializer
。这可以通过使用[ProtoInclude(...)]
来指定预期的具体类型来完成。
如果您真的无法提前知道实际类型,还有一个DynamicType
选项,它将AssemblyQualifiedName 写入流中。如果您对这条路线感兴趣,请注意该格式的“跨平台”功能开始失效,但它对于 .NET 到 .NET 的目的非常有用。
最简单的包装器,例如:
[ProtoContract]
public class SomeWrapper
[ProtoMember(1, DynamicType = true)]
public object Value get;set;
将您的对象包装在 that 中,它应该可以正常工作(至少在 v2 中;DynamicType 在 v1 中不存在)。完整示例:
[TestFixture]
public class SO7218127
[Test]
public void Test()
var orig = new SomeWrapper Value = new SubType Foo = 123, Bar = "abc";
var clone = Serializer.DeepClone(orig);
Assert.AreEqual(123, orig.Value.Foo);
Assert.AreEqual("abc", ((SubType) clone.Value).Bar);
[ProtoContract]
public class SomeWrapper
[ProtoMember(1, DynamicType = true)]
public BaseType Value get; set;
[ProtoContract]
public class BaseType
[ProtoMember(1)]
public int Foo get; set;
[ProtoContract]
public class SubType : BaseType
[ProtoMember(2)]
public string Bar get; set;
【讨论】:
以上是关于带有未知子类的 Protobuf-net 异常的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 protobuf-net 异常的代理对 List<T> 进行序列化