title: Protobuf-net won't deserialize data from Protobuf.js
body: <p>I'm using Protobuf for the communication between my web client and server (C#), using WebSocket. On the client, the de/serialization is done through <a href="https://github.com/dcodeIO/ProtoBuf.js/" rel="nofollow">Protobuf.js</a> and, on the server, using protobuf-net.</p>
  
  <p>The problem is that, when using aggregation with abstract classes, protobuf-net can't deserialize the data sent by Protobuf.js.</p>
  
  <p>This is the stack trace:</p>
  
  <pre><code>ProtoException: No parameterless constructor found for Base.
  at ProtoBuf.Meta.TypeModel.ThrowCannotCreateInstance(Type type) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 1397
  at proto_6(Object , ProtoReader )
  at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line 57
  at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 775
  at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) na c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 579
  at ProtoBuf.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) na c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 566
  at proto_2(Object , ProtoReader )
  at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line 57
  at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 775
  at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 700
  at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 589
  at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 566
  at ProtoBuf.Serializer.Deserialize[T](Stream source) na c:\Dev\protobuf-net\protobuf-net\Serializer.cs:line 77
  at ProtobufPolymorphismTest.Program.Main(String[] args) na c:\Desenvolvimento\Testes\ProtobufPolymorphismTest\ProtobufPolymorphismTest\Program.cs:line 30
  at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
  at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Threading.ThreadHelper.ThreadStart()
  </code></pre>
  
  <p>This is the contract:</p>
  
  <pre><code>[ProtoContract]
  [ProtoInclude(100, typeof(Child))]
  abstract class Base
  {
      [ProtoMember(1)]
      public int BaseProperty { get; set; }
  }
  
  [ProtoContract]
  class Child : Base
  {
      [ProtoMember(1)]
      public float ChildProperty { get; set; }
  }
  
  [ProtoContract]
  class Request
  {
      [ProtoMember(1)]
      public Base Aggregate { get; set; }
  }
  </code></pre>
  
  <p>And this is the code to reproduce the error. As the serialization is working, I'm only providing the result as a byte array. If it helps, I can provide the steps I took to get to the serialized values.</p>
  
  <pre><code>// This is the object serialized
  Child child = new Child() { ChildProperty = 0.5f, BaseProperty = 10 };
  Request request = new Request() { Aggregate = child };
  
  // This is the byte representation generated by protobuf-net and Protobuf.js
  byte[] protoNet = new byte[] { 10, 10, 162, 6, 5, 13, 0, 0, 0, 63, 8, 10 };
  byte[] protoJS = new byte[] { 10, 10, 8, 10, 162, 6, 5, 13, 0, 0, 0, 63 };
  
  // Try to deserialize the protobuf-net data
  using (System.IO.MemoryStream ms = new System.IO.MemoryStream(protoNet))
  {
      request = Serializer.Deserialize&lt;Request&gt;(ms); // Success
  }
  
  // Try to deserialize the Protobuf.js data
  using (System.IO.MemoryStream ms = new System.IO.MemoryStream(protoJS))
  {
      request = Serializer.Deserialize&lt;Request&gt;(ms); // ProtoException: No parameterless constructor found for Base.
  }
  </code></pre>
  
  <p>If I add SkipConstructor = true on the Base class definition, the error changes to "MemberAccessException: Cannot create an abstract class" with the following stack trace. If I remove the abstract from the Base class definition, it works as expected.</p>
  
  <pre><code>System.MemberAccessException: Cannot create an abstract class.
  at System.Runtime.Serialization.FormatterServices.nativeGetUninitializedObject(RuntimeType type)
  at ProtoBuf.BclHelpers.GetUninitializedObject(Type type) na c:\Dev\protobuf-net\protobuf-net\BclHelpers.cs:line 38
  at proto_6(Object , ProtoReader )
  at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line 57
  at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 775
  at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) na c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 579
  at ProtoBuf.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) na c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 566
  at proto_2(Object , ProtoReader )
  at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line 57
  at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) na c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 775
  at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 700
  at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 589
  at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type) na c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 566
  at ProtoBuf.Serializer.Deserialize[T](Stream source) na c:\Dev\protobuf-net\protobuf-net\Serializer.cs:line 77
  at ProtobufPolymorphismTest.Program.Main(String[] args) na c:\Desenvolvimento\Testes\ProtobufPolymorphismTest\ProtobufPolymorphismTest\Program.cs:line 30
  at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
  at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Threading.ThreadHelper.ThreadStart()
  </code></pre>
  
  <p>I'm not sure why the binary representation generated through protobuf-net and Protobuf.js are different, but they both seem valid as it works if the Base class is not abstract.</p>
  
  <p>Any ideas on why this is happening or a way to work around without removing the abstract from Base class?</p>
  
  <p>Thanks in advance!</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This is the code I used to generate the byte serialization through Protobuf.js:</p>
  
  <pre><code>&lt;script src="//raw.githubusercontent.com/dcodeIO/ByteBuffer.js/master/dist/ByteBufferAB.min.js"&gt;&lt;/script&gt;
  &lt;script src="//cdn.rawgit.com/dcodeIO/ProtoBuf.js/master/dist/ProtoBuf.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
      // Proto file
      var proto = "";
      proto += "package ProtobufPolymorphismTest;\r\n\r\n";
      proto += "message Base {\r\n";
      proto += "    optional int32 BaseProperty = 1 [default = 0];\r\n";
      proto += "    // the following represent sub-types; at most 1 should have a value\r\n";
      proto += "    optional Child Child = 100;\r\n";
      proto += "}\r\n\r\n";
      proto += "message Child {\r\n";
      proto += "    optional float ChildProperty = 1 [default = 0];\r\n";
      proto += "}\r\n\r\n";
      proto += "message Request {\r\n";
      proto += "    optional Base Aggregate = 1;\r\n";
      proto += "}";
  
      // Build the entities
      var protoFile = dcodeIO.ProtoBuf.loadProto(proto);
      var requestClass = protoFile.build("ProtobufPolymorphismTest.Request");
      var baseClass = protoFile.build("ProtobufPolymorphismTest.Base");
      var childClass = protoFile.build("ProtobufPolymorphismTest.Child");
  
      // Build the request
      var base = new baseClass();
      base.BaseProperty = 10;
      base.Child = new childClass();
      base.Child.ChildProperty = 0.5;
      var request = new requestClass();
      request.Aggregate = base;
  
      // Serialize
      var bytes = new Uint8Array(request.toArrayBuffer());
      var str = "new byte[] { " + bytes.join(", ") + " };";
      console.log(str);
  &lt;/script&gt;
  </code></pre>
  
  <p><strong>WORKAROUND</strong></p>
  
  <p>As Marc explained, protobuf-net doesn't support polymorphism when the field order is inverted. As a workaround, specific to Protobuf.js, you can change the order of the fields in the .proto file for it to serialize in the correct order.</p>
  
  <p>In my case, changing the .proto file to the following solved the problem:</p>
  
  <pre><code>package ProtobufPolymorphismTest;
  
  message Base {
     // the following represent sub-types; at most 1 should have a value
     optional Child Child = 100;
     optional int32 BaseProperty = 1 [default = 0];
  }
  message Child {
     optional float ChildProperty = 1 [default = 0];
  }
  message Request {
     optional Base Aggregate = 1;
  }
  </code></pre>
  
  <p>(Note the <code>optional Child Child = 100;</code> <em>before</em> the <code>BaseProperty</code>)</p>