protobuf-net игнорирует [KnownType] и требует добавления ProtoInclude - PullRequest
4 голосов
/ 29 сентября 2011

с использованием 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);

Поле Id абстрактного класса Message не сериализовано.

Чтобы это работало, я должен украсить сообщение:

[ProtoInclude(1, typeof(LoginRequest))]

Почему это? Я прочитал этот похожий вопрос , но Марк приходит к выводу, что "это больше не требуется в v2 - вы можете указать это во время выполнения или использовать DynamicType"

Я бы предпочел не указывать ничего, кроме KnownType

1 Ответ

1 голос
/ 29 сентября 2011

[KnownType(...)] недостаточно, поскольку библиотеке также необходимо использовать уникальное (для этого типа) целое число для использования в качестве ключа (1 в примере). Логически выводить его слишком рискованно, так как это может привести к неожиданным сбоям при настройке типа (а безопасность версий - это очень преднамеренная цель проектирования).

Если вы не хотите добавлять атрибут для этого, вы можете сказать ему, что ему нужно во время выполнения, то есть (в вашем коде запуска):

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