4

Using latest 2.0 beta version of ProtoBuf.net I am trying to serialize derived class(just example) and I get empty file. Why base class properties is not serialized?

[ProtoContract]
[Serializable]
public class Web2PdfClient : Web2PdfEntity
{

}

[ProtoContract]
[Serializable]
public class Web2PdfEntity : EngineEntity
{

    [ProtoMember(1)]
    public string Title { get; set; }
    [ProtoMember(2)]
    public string CUrl { get; set; }
    [ProtoMember(3)]
    public string FileName { get; set; }

}


[ProtoContract]
[Serializable]
public class EngineEntity
{

    public bool Result { get; set; }
    public string ErrorMessage { get; set; }
    public bool IsMembershipActive { get; set; }
    public int ConversionTimeout { get; set; }
    public byte[] FileStorage { get; set; }
}

While using code below to serialize class I get empty file.

var Web2PDF = new Web2PdfClient
                          {                                
                              CUrl = "http://www.google.com",
                              FileName = "test.txt"
                          };
        using (var file = File.Create(@"C:\Users\Administrator\Projects\temp\test.bin"))
        {
            Serializer.Serialize(file, Web2PDF);

        }
Tomas
  • 17,551
  • 43
  • 152
  • 257

1 Answers1

6

Actually, I'm quite surprised that didn't throw an exception - I will investigate! In order for that to work, the base-type must have a unique way to indicate each of the sub-types. This can be specified via attributes, or (in v2) at runtime. For example:

[ProtoContract]
[Serializable]
public class Web2PdfClient : Web2PdfEntity
{

}

[ProtoContract]
[ProtoInclude(7, typeof(Web2PdfClient))]
[Serializable]
public class Web2PdfEntity : EngineEntity
{ ... }

There's nothing special about 7 except that it shouldn't collide with any other members defined for that type. Multiple subtypes can be defined (with different tags). Note also that protobuf-net doesn't look at [Serializable], so you don't need that unless you are also using BinaryFormatter (or similar).

Similarly, EngineEntity should advertise its expected subtypes, and should indicate the members to serialize (and against which tag).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Marc, I have additional question, hope it is ok to ask using comment because it is related to this question. You said that Base class must be marked with attribute which indicate inherited class. What to do if Base class is located in separated class library? I can't put [ProtoInclude(7, typeof(MyInheritedClass))] on Base class because I will get error that MyInheritedClass is not resolved. – Tomas Jun 22 '11 at 06:28
  • 1
    @Tomas - if the base-type doesn't know about the derived types, then you can also configure it at runtime in v2 using a TypeModel and AddSubType; i.e. `typeModel.Add(typeof(Web2PdfEntity), false).AddSubType(7, typeof(Web2PdfClient));` and use `typeModel.Serialize` etc (cache and re-use the model, as it involves generated IL etc) – Marc Gravell Jun 22 '11 at 06:40