【问题标题】:protobuf-net ignores [KnownType] and requires ProtoInclude to be addedprotobuf-net 忽略 [KnownType] 并要求添加 ProtoInclude
【发布时间】:2011-11-27 15:00:27
【问题描述】:

使用 protobuf-net.dll 2.0.0.431

我正在尝试使用 [DataContract] 和 [DataMember] 序列化类层次结构。

[DataContract]
[KnownType(typeof(LoginRequest))]    
public class Message
{
    [DataMember(Order = 2)]
    public int Id { get; set; }
}

[DataContract]
public class LoginRequest : Message
{
    [DataMember(Order = 1)]
    public string Username { get; set; }

    [DataMember(Order = 2)]
    public string Password { get; set; }                
}

并序列化/反序列化:

            using (var file = File.Create(filename))
            {
                Serializer.Serialize(file, loginRequest);
            }

            LoginRequest deserialized;
            using (var file = File.OpenRead(filename))
            {
                deserialized = Serializer.Deserialize<LoginRequest>(file);
            }

            ReflectionUtils.Compare(loginRequest, deserialized);

抽象类MessageId字段没有序列化。

为了让它工作,我必须用以下方式装饰消息:

[ProtoInclude(1, typeof(LoginRequest))]

这是为什么?我已经阅读了this similar question,但 Marc 得出的结论是“v2 不再需要这个 - 你可以在运行时指定它,或者使用 DynamicType”

除了KnownType之外,我不希望指定任何其他内容

【问题讨论】:

    标签: c# serialization protobuf-net


    【解决方案1】:

    [KnownType(...)] 是不够的,因为库还需要一个唯一的(针对该类型的)整数作为键(示例中的 1)。以 qutomatically 推断它的风险太大,因为它可能会在调整类型时导致意外中断(并且版本安全是一个非常深思熟虑的设计目标)。

    如果您不想为此添加属性,您可以在运行时告诉它它需要什么,即(在您的启动代码中):

    RuntimeTypeModel.Default[typeof(Message)]
        .AddSubType(1, typeof(LogonRequest));
    

    【讨论】:

    • 这不是一个大问题,它只是将属性装饰的高度加倍。 :) 虽然关于这个主题,并且没有发布另一个问题或任何代码示例(尽管我可能必须这样做) - 我正在用[ProtoBehaviorAttribute] 装饰我的IService - 我发现我必须添加[KnownType][ProtoInclude(x)] 都有序列化工作。如果我排除 ProtoInclude 客户端可以接收(?)但不能发送消息。如果我排除 [KnownType] 则服务器无法发送消息(但没有错误,通道只是故障!)你能评论吗?
    • @wal 老实说这对我来说是新的;我必须调查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多