Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't my List<Foo> serialize with protobuf-net?

[DataContract] public class Foo 
{
   [DataMember(Order = 1)] public int FooId { get; set; }
}

[DataContract] public class Bar : Foo 
{
   [DataMember(Order = 2)] public string Name { get; set; }
}

[DataContract] public class Baz : Bar
{
    [DataMember(Order = 3)] public string BazName { get; set; }
}

Then, in code I setup a new TypeModel and add my subtypes

_ProtobufSerializer = TypeModel.Create();
_ProtobufSerializer.Add(typeof(Bar), true);
_ProtobufSerializer.Add(typeof(Baz), true);
var type = _ProtobufSerializer.Add(typeof(Foo), true);
type.AddSubType(100, typeof(Bar));
type.AddSubType(101, typeof(Baz));

Now, I can serialize instances of Foo, Bar and Baz fine. If I serialize

var listThatWorks = new List<Foo> { new Foo { FooId = 12 } }
var anotherListThatWorks = new List<Foo> { new Bar { FooId = 12, Name = "Test" } }

That works fine. However, if I serialize

var fails = new List<Foo> { new Baz { FooId = 12, Name = "Test" } }

Then I get an InvalidOperationException with message "Unexpected sub-type: Baz". What am I doing wrong? Is it just a bad idea to use sub-types with protobuf-net?

Also, thanks to @BFree for helping me figure out this is related to having two levels of subclasses.

like image 342
AgileJon Avatar asked Mar 29 '12 14:03

AgileJon


1 Answers

Got it. Really, I should give credit to BFree. He put together a runnable sample app that showed me my original post was too simplified. The real problem was my object model where Baz was a subclass of Bar which was itself a subclass of Foo. When I setup the TypeModel I didn't correctly specify this structure. Should have been:

_ProtobufSerializer = TypeModel.Create();
_ProtobufSerializer.Add(typeof(Baz), true);
var barType = _ProtobufSerializer.Add(typeof(Bar), true);
var fooType = _ProtobufSerializer.Add(typeof(Foo), true);
fooType.AddSubType(100, typeof(Bar));
barType .AddSubType(101, typeof(Baz));

I'm actually not sure about the order values, but I know those work.

like image 184
AgileJon Avatar answered Oct 11 '22 10:10

AgileJon