у нас есть некоторые проблемы с сериализацией пустого списка. здесь некоторый код в.NET с помощью CF 2.0
//Generating the protobuf-msg
ProtoBufMessage msg = new ProtoBufMessage();
msg.list = new List<AnotherProtobufMessage>();
// Serializing and sending throw HTTP-POST
MemoryStream stream = new MemoryStream();
Serializer.Serialize(stream, msg);
byte[] bytes = stream.ToArray();
HttpWebRequest request = createRequest();
request.ContentLength = bytes.Length ;
using (Stream httpStream = request.GetRequestStream())
{
httpStream.Write(bytes, 0, bytes.Length);
}
мы получили исключение, когда мы пытаемся записать на потоке (bytes.length из диапазона). Но тип с пустым Списком не должен составлять 0 байтов, право (информация типа?)?
Нам нужен этот тип отправки, потому что в Ответе сообщения с Сервера для нашего клиента.
Формат передачи (определенный Google - не в моем распоряжении!) Отправляет данные только для элементов . Он не делает различий между пустым списком и пустым списком. Так что, если нет данных для отправки - да, длина равна 0 (это очень скромный формат ;-p).
Буферы протокола не содержат метаданных какого-либо типа в сети.
Еще одна распространенная ошибка заключается в том, что вы можете предположить, что ваше свойство list автоматически создается как пустое, но это не так (если ваш код не делает этого, возможно, в инициализаторе поля или конструкторе).
Вот работоспособный прием:
[ProtoContract]
class SomeType {
[ProtoMember(1)]
public List<SomeOtherType> Items {get;set;}
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return Items != null && Items.Count == 0; }
set { if(value) {Items = new List<SomeOtherType>();}}
}
}
Возможно, хакерский, но он должен работать. Вы также можете потерять "набор" Items
, если хотите, и просто отбросьте bool
:
[ProtoMember(1)]
public List<SomeOtherType> Items {get {return items;}}
private readonly List<SomeOtherType> items = new List<SomeOtherType>();
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return items.Count == 0; }
set { }
}