Сериализация перечисления protobuf-net

Что нужно сделать, чтобы сериализовать перечисления с помощью protobuf-net? Я получаю указанную ниже ошибку при сериализации класса, имеющего свойство enum, если атрибут DataMember удален из объявления свойства, он работает нормально.

"System.InvalidOperationException: могут обрабатываться только классы контрактов данных (и их списки / массивы)"


person Kimi    schedule 09.11.2010    source источник
comment
У вас есть пример? Это должно работать нормально ...   -  person Marc Gravell    schedule 10.11.2010
comment
Привет, Марк! Спасибо за сообщение о десеризации List ‹T› с помощью Protobuf.net. У меня такая же проблема. Я опубликую пример ниже.   -  person Andrew Kalashnikov    schedule 15.11.2010
comment
Предупреждаем, этот вопрос обсуждается в мета. Есть ли причина, по которой вы откатили редактирование, включая MCVE? Ваша ситуация отличалась от ситуации с Эндрюсом?   -  person Rob    schedule 02.05.2018


Ответы (2)


Я подозреваю, что на самом деле это 2 разных сценария, но что касается образца кода, добавленного Эндрю, это связано с тем, что он не может (заранее) выяснить, что он собирается делать по умолчанию значения (по умолчанию данные обрабатываются как необязательные у получателя). Есть 3 способа исправить это:

1: добавьте перечисление со значением 0 (поскольку 0 всегда является значением CLI по умолчанию для нулей), например

public enum SiteType
{
    Error = 0,
    ...

2: укажите, какое значение использовать по умолчанию:

[ProtoMember(10), DefaultValue(SiteType.Partition)]
public SiteType Type { get; set; }

3: сообщите движку, что ему действительно не нужно об этом беспокоиться, т.е. что он будет иметь значение:

[ProtoMember(10, IsRequired = true)]
public SiteType Type { get; set; }
person Marc Gravell    schedule 15.11.2010
comment
Спасибо. Теперь это работает! С помощью protobuf-net я уменьшаю свой трафик, увеличивая скорость до 10 раз с помощью службы WCF. Это действительно мощный способ поднять производительность. Думаю, это должен быть обычный способ работы с этим протоколом \ net. К сожалению, примеров применения protobuf.net с WCF не так много. - person Andrew Kalashnikov; 16.11.2010
comment
@Andrew - отзыв отмечен. Я постараюсь это исправить. - person Marc Gravell; 16.11.2010
comment
Моя проблема заключалась в том, что мы сериализовали список объектов, и одно из свойств не имело IsRequired = true. Думаю, в таком случае было бы неплохо включить внутреннее исключение. - person Kimi; 16.11.2010
comment
@Al - ок; Я настрою v2, чтобы сделать это более очевидным. В каком-то смысле я рад, что это была та же проблема, и теперь она решена. - person Marc Gravell; 16.11.2010
comment
Относится ли этот ответ к версии 2.0.0.480? - person Dan Ling; 09.05.2012
comment
@Otter в основном, но v2 также вводит возможность обрабатывать перечисления как обычные целые числа, а не применять обработку перечислений, что значительно упрощает работу с некоторыми сценариями; IIRC это автоматически включается для [Flags] перечислений. У вас есть конкретный сценарий, с которым я могу помочь? - person Marc Gravell; 09.05.2012

Образец:

[DataContract]
[ProtoContract]
public enum SiteType
{
    [EnumMember]
    [ProtoEnum]
    Site = 1,
    [EnumMember]
    [ProtoEnum]
    Partition = 2,
    [EnumMember]
    [ProtoEnum]
    Module = 3
}

[DataContract]
[Serializable]
[ProtoContract]
public class SiteDTO
{
    [DataMember]
    [ProtoMember(1)]
    public int Id { get; set; }
    ...
    [DataMember]
    [ProtoMember(10)]
    public SiteType Type { get; set; }
}
person Andrew Kalashnikov    schedule 15.11.2010
comment
Спасибо за пример Андрей. Теперь у меня есть это на месте, и я буду работать над этим. Я представляю, что он просто переходит в восторг от решения, что это сложный объект. Я полагаю, что в моем использовании WCF я просто никогда не украшал перечисления [DataContract]. Я еще не проверял, но я предполагаю, что все работает нормально, если вы удалите атрибуты в перечислении? - person Marc Gravell; 15.11.2010
comment
когда я пытаюсь это сделать, я получаю ошибку о значении перечисления по умолчанию (это то, что вы видите?), которое на самом деле не то же самое, что сообщил Al. Однако я добавил ответ, который, как мне кажется, касается вашего вопроса. - person Marc Gravell; 15.11.2010