Сериализация пуста - PullRequest
       2

Сериализация пуста

2 голосов
/ 18 февраля 2012

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

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

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

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

1 Ответ

2 голосов
/ 18 февраля 2012

Сериализация объекта без интересных полей для записи не является ошибкой как таковой - довольно необычной, но не совсем ошибкой - так и есть: она не жалуется. Нулевые байты - это допустимая длина сериализации для protobuf, даже с полями для сериализации (если все они оказываются пустыми / default-value / conditional-and-disabled / etc). Фактически, это произошло ранее на этой неделе, потому что новый MS WebAPI предполагает (неправильно в данном случае), что длина полезной нагрузки нулевых байтов невозможна, и поэтому не вызывает десериализатор . Вздох.

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

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

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

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

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

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

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

...