Search code examples
c#serializationprotobuf-net

protobuf does not deserialize object corrctly


I have three classes:

[ProtoContract]
public class Message
{
    [ProtoMember(1)]
    public int MethodId { set; get; }
    [ProtoMember(2)]
    public CustomArgs Arguments { set; get; }
}

[ProtoContract]
public class CustomArgs
{
    [ProtoMember(1)]
    public int IntVal { set; get; }
    [ProtoMember(2)]
    public string StrVal { set; get; }
    [ProtoMember(3)]
    public CycleData Cd { set; get; }
}

[ProtoContract]
public class CycleData
{
[ProtoMember(1)]
public int Id { set; get; }
[ProtoMember(2, AsReference = true)]
public CycleData Owner { set; get; }}

So when I create objects then serialize and deserialize it the Arguments property stay null but orignal object have a value. The sample code is:

static void Main(string[] args)
{
    CycleData cd = new CycleData()
    {
        Id = 5
    };
    cd.Owner = cd;

    CustomArgs a = new CustomArgs()
    {
        IntVal = 5,
        StrVal = "string",
        Cd = cd
    };

    Message oldMsg = new Message()
    {
        MethodId = 3,
        Arguments = a
    };

    Stream st = new MemoryStream();
    ProtoBuf.Serializer.Serialize(st, oldMsg);
    var newMsg = ProtoBuf.Serializer.Deserialize<Message>(st);

}

So newMsg.Arguments is null after deserialize. What i do wrong?


Solution

  • You have a simple error. Once you serialize/write to the memstream, the .Pointer remain at the end of the stream. Deserializing immediately after using on the same stream fails because there is nothing to read after that point. Just reset it:

    using (Stream st = new MemoryStream())
    { 
        ProtoBuf.Serializer.Serialize(st, oldMsg);
        st.Position = 0;          // point to start of stream
        var newMsg = ProtoBuf.Serializer.Deserialize<Message>(st);
    }
    

    I also put the stream in a using block to dispose of it.