4

Is it possible to serialize complex object with Protocol Buffers C# (ProtoBuf-net) without using Protocontract and proto files ?

[ProtoBuf.ProtoContract(ImplicitFields = ProtoBuf.ImplicitFields.AllPublic)]

I have tried to use the ProtoContract but even then I can't serialize object (It is a LLBLGen ORM object).

Kevin Montrose
  • 22,191
  • 9
  • 88
  • 137
khorvat
  • 1,630
  • 2
  • 20
  • 31

1 Answers1

4

Yes; there are various options here;

  • firstly, note that "implicit fields" is brittle if you add members, since it has to make more guesses than I would like; only use that with stable contracts
  • you can apply a default behaviour globally via GlobalSettings, but I tend to advise against it
  • protobuf-net v1 can also work with:
    • XmlType/XmlElement attribute pairs, as long as the XmlElement specifies an Order
    • DataContract/DataMember attribute pairs, as long as the DataMember specifies an Order
    • partial classes; even for properties, via ProtoPartialMember attribute(s), etc
  • protobuf-net v2 can be used 100% without attributes of any kind, by using a TypeModel to describe the interesting types at runtime; this can also compile the model to a dedicated serialization dll if you need (in particular for use with AOT-dependent devices)

I can advise more, but there are a number of options presented; tell me which is/are most appropriate and I can add more detail.

Re .proto files; those are (and have always been) entirely optional with protobuf-net, as I recognise that there are a lot of cases where a code-first approach (or retrofit of serialization to an existing model) is useful. Three is a code-generator if you choose to use .proto, of course.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Hi, I'm not using .proto files, DataContracts and I have removed the "implicit fields" I have downloaded the v2 from your repository and I'm not able to serialize any of my entities generated by LLBLGen Pro. Here is the code I'm using: – khorvat May 11 '11 at 13:49
  • `ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(DAL.EntityClasses.RequestExaminationEntity), true); ProtoBuf.Serializer.PrepareSerializer(); ProtoBuf.Serializer.Serialize(m, DataSource[0]); byte[] arrProto = m.ToArray(); var entity = ProtoBuf.Serializer.Deserialize(new MemoryStream(arrProto));` – khorvat May 11 '11 at 13:50
  • I'm getting byte[] with zero length after serialization. And thanks for your fast reply :) – khorvat May 11 '11 at 13:51
  • @khorvat it still needs to know which members to serialize (and with which tags) - the "true" (for defaults) won't have anything to apply without attributes to guide it. You should be able to add the members to the MetaType? I also need to add an "implicit fields" option to that API... – Marc Gravell May 11 '11 at 17:42
  • I'm sending you a sample via e-mail that I can't get to work, I'm obviously missing something. Can you please take a look at the code and point me what to fix. As I’m using ORM tool and I can’t use any of the attributes so I’m using the v2. Also I has to change MetaType class (constructor was internal) to add members dynamically. Thanks – khorvat May 12 '11 at 11:35
  • @khorvat - there should be no need to change MetaType, but I'll review – Marc Gravell May 12 '11 at 11:39
  • Example that you have sent me is working fine, thanks for everything. I'll try this on a larger scale project and see how it goes. – khorvat May 13 '11 at 14:42
  • Could you share the code in that email. I'm trying exactly the same with a class tree of autogenerated code from an xsd. – graffic Nov 24 '11 at 12:00
  • @graffic the easiest option here is just to add a partial class and decorate that with ProtoContract/ProtoPartialMember attributes; do you need a non-attribute approach? – Marc Gravell Nov 24 '11 at 12:32
  • @MarcGravell Since it has around 100 autogenerated classes. I was looking for a recursive ImplicitFields. protobuf-net is open source so it's time to contribute if you find it useful. – graffic Nov 28 '11 at 14:23
  • @graffic my main concern is making it too easy for people to cause harm to their own data; and an open "just make it work" button does exactly that - any changes to that data will now presumably be breaking, which is not ideal. Thoughts? – Marc Gravell Nov 28 '11 at 14:33
  • @MarcGravell Unfortunately (for me), you're right, it would be dangerous. At least if I could Add a type with the the ImplicitFields flag on. Currently I create a TypeModel and add the types via reflection. Then I feed the configured TypeModel via DI. – graffic Dec 05 '11 at 16:29
  • @graffic TypeModel support for implicit fields is on my list to add – Marc Gravell Dec 05 '11 at 17:39
  • foreach (var tfType in tfTypes) { var type = typeModel.Add(tfType, false); type.Add(tfType.GetProperties(BindingFlags.Instance).Select(x => x.Name).ToArray()); } – graffic Dec 06 '11 at 12:49
  • @graffic that is not actually stable; GetProperties does not guarantee any particular order, and the order here is **really** important – Marc Gravell Dec 06 '11 at 12:54