2012-02-18 4 views
1

Я использую V2 прото-buf. Когда я сериализую пример проекта с двумя классами, proto-buf сериализуется, когда я не включаю [ProtoMember (x)] в поля. Я просто поставил [ProtoContract] перед классами. Я не знаю, почему это происходит?Сериализация пуста

Когда я попытался сериализовать свой реальный проект после помещения [ProtoContract] перед всеми классами и не добавляя [ProtoMember (x)] для любых полей в любых классах, я не получаю ошибку, но сериализованный файл пуст (0 байтов). Кто-нибудь знает, что происходит? Нужно ли нам помещать protemember перед каждым полем для сериализации? Если да, то почему мой примерный проект стал сериализован без использования какого-либо прогеммера в проекте?

Мой настоящий проект имеет примерно 20-30 классов, каждый из которых имеет много полей? Нужно ли мне помещать protemember во все поля во всех классах?

Спасибо за понимание.

ответ

1

Сериализация объекта без каких-либо интересных полей для записи не является ошибкой как таковой - довольно необычная, но не строго ошибка - так действительно: она не жалуется. Zero bytes - допустимая длина сериализации для protobuf, даже с полями для сериализации (если все они оказываются нулевыми/по умолчанию/условно-выключенными/и т. Д.). Фактически, это наступило раньше на этой неделе, потому что новый MS WebAP предполагает (в данном случае неверно), что длина полезной нагрузки нулевых байтов невозможна, и поэтому не вызывает десериализатор. Вздох.

Но чтобы ответить на ваш вопрос!

Если вы абсолютно убедитесь, что вы не собираетесь менять DTO, вы можете попросить protobuf-net составить цифры; это «ImplicitFields», и может быть сделано либо в виде:

  • всех общественных членов (полей или свойств) - это очень нравится, как XmlSerializer работает
  • все поля (частные или государственные) - это очень похоже на то, как работает BinaryFormatter.

Единственная проблема с ImplicitFields заключается в том, что числа, которые он генерирует, по сути являются контрактом. ImplicitFields генерирует числа, упорядочивая их в алфавитном порядке и просто используя последовательный номер. Если вы измените свой DTO (добавьте/удалите/переименуйте элемент), он может начать думать о разных номерах, что является нарушением изменений: любые старые данные на диске/в базе данных/etc могут не десериализоваться правильно.

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

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)] 
public class Foo { /* blah blah blah */ } 

Конечно, вы всегда можете изменить к явному [ProtoMember(n)] позже - просто используйте 1, 2, 3 и т. д. в соответствии с макетом алфавитного элемента, а затем внесите любые изменения, которые вы хотите внести в DTO.

Смежные вопросы