2
votes

How do I specify the ProtoBuf-Net attributes in classes of a WebReference?

I have a .net 2.0 Web Service in which I am creating a byte[] using protobuf. In my client (v3.5) I want to deserialize the byte[] into the respective class. However, when I deserialize all I get is 0 and nulls.

The reason for this is I specify the type as the Web Reference class.

Does Not Work Correctly

using (MemoryStream stream = new MemoryStream(byteArray))
{
            List<WebReferencePerson> personsList =  Serializer.DeserializeWithLengthPrefix<List<WebReferencePerson>>(stream, PrefixStyle.Base128);
            stream.Close();
}

However, if I create another class Person1 in the client and specify the Proto attributes [ProtoContract] and [ProtoMember()], I get the correct data deserialized. i.e.

[ProtoContract]
class Person1
{
    [ProtoMember(1)]
    string Name {get;set;}
    [ProtoMember(2)]
    int Id {get;set;}
}

This works fine.

List<Person1> personsList = 
Serializer.DeserializeWithLengthPrefix<List<Person1>>(stream, PrefixStyle.Base128);

Isn't there a way to use the classes from the Web Reference to deserialize the data? How can I specify the Protobuf attributes to Web Reference class? OR Do I have to specify a different class with the Proto attributes to deserialize the data from a WebService?

1

1 Answers

0
votes

The asmx-generated types won't have tag-markers markers; there are a number of ways of getting around this:

  • deserialize into the protobuf DTO
  • use a partial class to tell it about the layout
  • define the layout in code

The second option would look like:

namespace Your.Namespace {
    [ProtoContract]
    [ProtoPartialMember(1, "Name")]
    [ProtoPartialMember(2,  "Id")]
    partial class WebReferencePerson {}
}

The third option would be, as part of app-start:

RuntimeTypeModel.Default.Add(typeof(WebReferencePerson), false)
                    .Add("Name", "Id");

With either of these approaches it should then deserialize.