Jeff
Jeff

Reputation: 36573

Protobuf-net not serializing base class members

We have the following classes and WCF service (using protobuf-net for serialization):

[DataContract]
[KnownType(typeof(NamedViewModel))]
public class NamedViewModel<TKey> : IViewModel
{
    [DataMember]
    public virtual TKey Id { get; set; }

    [DataMember]
    public virtual string Name { get; set; }
}

[DataContract]
[KnownType(typeof(ScheduleTemplateViewModel))]
public class NamedViewModel : NamedViewModel<int>
{
}

[DataContract]
public class ScheduleTemplateViewModel : NamedViewModel
{
    [DataMember]
    public string Comment { get; set; }
}

[DataContract]
public class Container
{
    [DataMember]
    public IEnumerable<ScheduleTemplateViewModel> Templates { get; set; }
}

[ServiceContract]
public interface IService
{
    [OperationContract]
    Container Get();
}

public class Service : IService
{
    public IEnumerable<Container> Get()
    {
        return new Container { Templates = Enumerable.Range(1, 10)
            .Select(i => CreateTemplate()).ToArray() };
    }

    private void ScheduleTemplateViewModel CreateTemplate()
    { 
        var instance = WindsorContainer.Resolve<ScheduleTemplateViewModel>();
        // populate instance
        return instance;
    }
}

We have two problems:

  1. We get an exception during serialization that the Castle DynamicProxy type for ScheduleTemplateViewModel is unexpected. We noticed that there is custom code in protobuf-net to handle NHibernate and EntityFramework proxies...but not Castle DynamicProxies. We worked around this by adding an additional case statement in the protobuf-net source code to check for Castle's IProxyTargetAccessor type...but it would be nice if there were a way of handling this without modifying the protobuf-net source code...

  2. Members on ScheduleTemplateViewModel (namely Comment) are serialized correctly...but base class Members are not. We already have the InferTagFromNameDefault set to true on RuntimeTypeModel.Default.

Upvotes: 2

Views: 1052

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062780

  1. I can add that; can you tell me the full name (including namespace) of that interface?

  2. From the example you give, none of those values should serialize, as none of them include the necessary numeric field-number information. Since you say some do serialize, I'm going to assume that this is an omission in the copy/paste. Protobuf-net will try to use the Order=n information from [DataMember(...)] if nothing better is available. However, if must be emphasized that protobuf-net cannot use [KnownType(...)], and inheritance again needs some explicit numeric field-number information. This is most easily added via [ProtoInclude(...)], but can also be provided at runtime

Upvotes: 1

Related Questions