4
votes

We recently upgraded protobuf-net from 2.0.0.668 to 2.3.2 for one of our projects and now we are running into issues when serializing one of the objects.

When serializing a property of type Dictionary<long, decimal?>, protobuf-net throws:

ProtoBuf.ProtoException: 'Data of this type has inbuilt behaviour, and cannot be added to a model in this way: System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

I read online that this has to do with the fact that this is a type that has a default serializer in protobuf-net. However, this did work in version 2.0.0.668 and the other property that is a decimal does not cause any problems. How can I solve this issue in my case?

[ProtoContract]
public class MyObject
{
    [ProtoMember(1)]
    public MyType TypeInstance { get; set; }

    [ProtoMember(2)]
    public Dictionary<long, decimal?> MyDictionary { get; set; }

    [ProtoMember(3)]
    public decimal Total { get; set; }
}
public class OtherClass
{
    public static byte[] ToProto<T>(T input)
    {
        byte[] bytResults;
        using (var stream = new MemoryStream())
        {
            Serializer.Serialize(stream, input);
            bytResults = stream.ToArray();
        }
        return bytResults;
    }
}

Edit: The proposed answer ina different question is not applicable. This question is not about decimals in Protocol Buffers, but about nullable decimals in newer versions of protobuf-net, which should be supported according to the documentation.

1
If that is the only reason serialization fails, why not just not store keys in the dictionary which lack a decimal value? (and remove the nullable declaration) - fredrik
@fredrik - decimal is already supported (that answer is from 2008 and very outdated). That's not the issue here. The problem is Nullable<decimal>. - Justin Niessner
@JustinNiessner kay then, vote retracted. - fredrik
@fredrik - Thanks, I've changed it to non-nullable decimal to work around this issue for now, but I would expect to be able to work with nullable, as the protobuf-net specification tells us that it should work. I hope that someone can clarify why this doesn't work and what I should do to make the nullable types work. - rperz86
See update in my answer: now fixed - Marc Gravell

1 Answers

1
votes

This is likely to be a glitch in the "map" detection (added in 2.3), and should be logged as a bug; however, I suspect a workaround can be achieved by disabling "map" support here:

[ProtoMember(2), ProtoMap(DisableMap = true)]
public Dictionary<long, decimal?> MyDictionary { get; set; }

Update: this was a bug and is fixed in 2.3.4