2
votes

I am trying to serialize my below class using protobuf but it is failing with "Object reference" error. more details as below. Any idea what could be wrong by looking into error details? Note: My User object is too large and it has so many child objects and properties. So not adding the User class details here.

[ProtoContract]
public class MyPrincipal
{

    public MyPrincipal(string Id, int myId)
    {
        this.Id = Id;
        this.MyId = myId;
        this.Principals = new Dictionary<MyPrincipalType, User>();         
    }

    [ProtoMember(1)]
    public string Id { get; set; }


    [ProtoMember(2)]
    public int MyId { get; set; }

    [ProtoMember(3)]
    public Dictionary<MyPrincipalType, User> Principals { get; set; }


    public MyPrincipal AddPrincipal(MyPrincipalType principalType, User principalValue)
    {
        this.Principals.Add(principalType, principalValue);
        return this;
    }
}


public enum MyPrincipalType
{
   Test = 0
}

Here are the error details:

Exception: {"Object reference not set to an instance of an object."}

Inner StrackTrace : at ProtoBuf.Serializers.TagDecorator.get_ExpectedType() at ProtoBuf.Serializers.DefaultValueDecorator..ctor(TypeModel model, Object defaultValue, IProtoSerializer tail) at ProtoBuf.Serializers.MapDecorator`3..ctor(TypeModel model, Type concreteType, IProtoSerializer keyTail, IProtoSerializer valueTail, Int32 fieldNumber, WireType wireType, WireType keyWireType, WireType valueWireType, Boolean overwriteList)

Outer StackTrace: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)at ProtoBuf.Meta.ValueMember.BuildSerializer() at ProtoBuf.Meta.ValueMember.get_Serializer() at ProtoBuf.Meta.MetaType.BuildSerializer() at ProtoBuf.Meta.MetaType.get_Serializer() at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, ProtoWriter dest) at ProtoBuf.Meta.TypeModel.SerializeCore(ProtoWriter writer, Object value) at ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value, SerializationContext context) at ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value) at ProtoBuf.Serializer.Serialize[T](Stream destination, T instance)

This issue is only with latest nuget Version 2.3.0. When I use version 2.0.0.668, this works fine.

1
Try adding a parameterless constructor as explained in Is it possible to use Protobuf-Net with a class without a parameterless constructor?.dbc
Thanks for quick reply. Tried but same error. Any other suggestions?Pratik Mehta
Your code doesn't compile since you don't include a definition for User. If I just add a type with no properties, I get a ProtoBuf.ProtoException: No parameterless constructor found for MyPrincipal as expected: fiddle. If I add a default constructor there's no exception: fiddle #2. Please provide a minimal reproducible example that actually reproduces the problem.dbc
Sure. Will paste example to reproduce the issue... And Principals property has attribute but missed while posting question.Pratik Mehta
Also when I change my property from public Dictionary<MyPrincipalType, User> Principals to public Dictionary<string, User> Principals this works with latest nuget version. Any suggestions?Pratik Mehta

1 Answers

0
votes

This is a library bug, and a nasty one by the look of it. I have logged it as an issue.

There is a workaround: explicitly disable "map" handling on the dictionary for now - add [ProtoMap(DisableMap = true)] to Principals. The code has been fixed, and this should be included in 2.3.1. I will review the other candidates for 2.3.1 and decide what warrants prompt release - moving the rest to 2.3.2 (so we can ship 2.3.1 with this fix ASAP).