2

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.

1 Answer 1

1
  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

Sign up to request clarification or add additional context in comments.

5 Comments

We have InferTagFromNameDefault set to true, so that's why we don't need the Order=n information. That's what that property does, right? Is there a way of dynamically/automatically adding the ProtoInclude to the RuntimeTypeModel at runtime? This is a client application, so I don't want to incur the hit at startup to add everything to the RuntimeTypeModel ahead of time... That is to say, is there a hook or event I can watch like RuntimeTypeModel.Default.TypeAdded += ...where I can put code to add the Include? I'm not so fond of putting non BCL attributes on all my types...
@JeffN825 my mistake for not spotting the "InferTagFromNameDefault". Hierarchy can be steered using RuntimeTypeModel.Default[baseType].AddSubType(...) - but that's about the best I can offer there
Thanks. So, no chance of adding some kind of hook or event that I can react to when protobuf-net encounters and auto-adds a new type to the RuntimeTypeModel?
Do you think you could add the Castle proxy support to the code base? Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.