2010-04-30 2 views
1

Я использую protobuf-net для сериализации и десериализации сообщений. Мое сообщение также содержит строки, которые могут быть пустыми. Однако, когда я десериализую их на другой стороне, я получаю пустые строки («»).null string deserialized to empty string при использовании protobuf-net

Согласно документам google, значение по умолчанию для строкового типа в пустой строке. Какая может быть резолюция по этому вопросу?

Вот код, я использую:

Command message = new Command(); 
message.s_value = null; 
using (MemoryStream stream = new MemoryStream()) 
{ 
    Serializer.Serialize<Command>(stream, message);     
    stream.Close(); 
} 

При десериализации тот же поток, я получаю s_value = ""

ответ

4

Я бы догадаться, что ваш тип явно устанавливающее строку «» в безпараметрический конструктор. Не могли бы вы проверить?

Способ, Protobuf-чистые ручки это:

  • для null, ничего посылается (провод-формат Protobuf не имеет возможности явно выражающий null, но мы можем рассматривать его как по желанию и опустить его)
  • для "", шаблон 0 длины посылается, который должен быть десериализации, как ""
  • для непустой строки, длина и строка посылается, и десериализации

Во время десериализации в корпусе null он просто покидает ваше поле/собственность в одиночку, так как у него нет данных для обработки. Если тип устанавливает значение по умолчанию "", он останется "".

Обратите внимание, что в версии «v2» (я ожидаю, что это будет выпущено в течение следующих двух недель), вы можете опционально указать ему, чтобы использовать подход WCF «не запускать какой-либо конструктор», который будет иметь эффект ухода это как null, даже если присваивает ему конструктор по умолчанию.

Есть также некоторые трюки, которые вы можете сделать (с «v1»), чтобы отправить флаг bool (как отдельное свойство) в категорию null; сообщите мне, если вы хотите пример этого.


Редактировать: здесь приведен пример трюка «v1», чтобы обойти это; «v2» подход «игнорировать конструктор», вероятно, является лучшим вариантом долгосрочного:

[DataContract] 
class Test { 
    public Test() { Value = ""; } // a constructor that assigns the value 

    [DataMember(Order = 1)] 
    public string Value { get; set; } // our standard data 
    [DataMember(Order = 2)] 
    private bool ValueIsNull { // only exists to indicate explicit null 
     get { return Value == null; } 
     set { Value = value ? null : (Value ?? "");} 
    } 
} 
+0

Я обновил вопрос и включил образец кода, который я тестирую. Я проверил код, и поле типа строки всегда инициализируется пустой строкой при объявлении. Я выяснил некоторые работы вокруг (как, например, вы упомянули, например), но я думал о достижении без включения дополнительной информации или изменения сгенерированного кода. – ata

+0

@ cornerback84 - этот код генерируется из .proto? Или ваш собственный генератор? –

+0

Код генерируется из .proto. Я использую protobuf-net компилятор для его создания (новая интеграция vs2008). – ata