Protobuf-net“反序列化期间引用跟踪对象更改引用”错误(2)

Posted

技术标签:

【中文标题】Protobuf-net“反序列化期间引用跟踪对象更改引用”错误(2)【英文标题】:Protobuf-net “a reference-tracked object changed reference during deserializartion” error (2) 【发布时间】:2012-08-01 15:43:27 【问题描述】:

冒着违反礼节的风险(如果有不当之处,我深表歉意),我喜欢提出这个问题,因为它已经流传了一段时间,没有一个答案。作为 Protobuf-net 库的一部分,我相信这实际上是一个更严重的错误(如果事实证明不是,我愿意道歉一千次):

尝试反序列化作为 DynamicType 对象一部分的值类型时,我仍然遇到上述错误。以下是用于序列化/反序列化的方法以及正在序列化和反序列化的特定类以及一些简单的测试代码:

[ProtoContract]
public class ZmqMessage

    [ProtoMember(1)]
    public ZmqMessageType MessageType  get; set; 
    [ProtoMember(2, DynamicType = true)]
    public object MessageBody  get; set; 

    public ZmqMessage()
     

    public ZmqMessage(ZmqMessageType zmqMessageType, object messageBody)
    
        this.MessageType = zmqMessageType;
        this.MessageBody = messageBody;
    




public static class ProtoBuf

    public static byte[] Serialize<T>(T serializeThis)
    
        using (var stream = new MemoryStream())
        
            Serializer.Serialize<T>(stream, serializeThis);
            return stream.GetBuffer();
        
    

    public static T Deserialize<T>(byte[] byteArray)
    
        using (var stream = new MemoryStream(byteArray))
        
            return Serializer.Deserialize<T>(stream);
        
    

这里有一些测试用例:

ZmqMessage testMessage = new ZmqMessage(ZmqMessageType.ControlMessage, "Test");
byte[] byteMessage = ProtoBuf.Serialize<ZmqMessage>(testMessage);
ZmqMessage deserializedMessage = ProtoBuf.Deserialize<ZmqMessage>(byteMessage);

ZmqMessage testMessage = new ZmqMessage(ZmqMessageType.ControlMessage, (int) 1);
byte[] byteMessage = ProtoBuf.Serialize<ZmqMessage>(testMessage);
ZmqMessage deserializedMessage = ProtoBuf.Deserialize<ZmqMessage>(byteMessage);

第一个 testMessage 反序列化很好,而第二个(在 messageBody 中使用 int)抛出上述错误消息。

【问题讨论】:

我将不得不进行调查,尽管几天前解决了这个问题的一个原因(继承,而不是动态) @MarcGravell,在此期间您知道解决方法吗?谢谢 不是不先看,不是 @MarcGravell,我附上了错误详细信息的屏幕截图,以防万一。非常感谢您愿意研究它。 让它站起来;至少听起来需要一些更好的错误消息。不过一个警告:你提到“子类”; DynamicType 目前很好地处理继承;我在那里有一些出色的工作要做。 【参考方案1】:

解决了这个问题,我忘记了我必须将子类标记为 [ProtoContract] 及其成员也标记为 [ProtoMembers(n)],即使将它们传递给“DynamicType”也是如此。请注意上面关于动态类型和继承的 Marc Gravell 的 cmets。

这不是一个错误,我很抱歉建议它作为一种可能性。

【讨论】:

以上是关于Protobuf-net“反序列化期间引用跟踪对象更改引用”错误(2)的主要内容,如果未能解决你的问题,请参考以下文章

protobuf-net:日期时间的编码

Protobuf-net:嵌套的 IEnumerable 对象

用于继承的 Protobuf-net .proto 文件生成

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

带有 Protobuf-net 的端点行为配置 WCF

Protobuf-net.Grpc 服务契约继承