Question

I'm trying to serialize a Dictionary with protobuf-net but still getting "Unexpected sub-type: " exception with generic lists.

This is how I construct the dictionary:

        var list = new List<DummyObject1>();
        list.Add(new DummyObject1());

        var dict = new Dictionary<string, object>();
        dict["0"] = new DummyObject1();
        dict["1"] = new DummyObject1();
        dict["2"] = list;

I added the types to the default model with

        model.Add(typeof(object), true);
        model.Add(typeof (DummyObject1), true);

Is there any solution or workaround for this situation?

Edit: I made it work with a workaround like this;

First I wrote a wrapper class for List

        public class ListWrapper
        {
            public List<object> Items { get; set; }
        }

and I registered the type and Items field

        ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(ListWrapper));
        ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(ListWrapper)].AddField(1, "Items");

Now I can serialize and deserialize a dictionary

        var dict = new Dictionary<string, object>();
        dict["0"] = new DummyObject1();
        var lw = new ListWrapper { Items = new List<object> { new DummyObject1() } };
        dict["2"] = lw;


        using (var stream = new MemoryStream())
        {
            Serializer.Serialize(stream, dict);
            stream.Seek(0, SeekOrigin.Begin);
            var req = Serializer.Deserialize<Dictionary<string, object>>(stream);
        }
Was it helpful?

Solution

Quite simply, protobuf-net does not play nicely with object, and will always struggle with (for example) a Dictionary<string,object>. That isn't a supported use case, as the google protobuf specification expects data to follow a single contract end-to-end. I can spoof around that for some inheritance scenarios, but object is just too vague.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top