Исключение при сериализации значений перечисления с атрибутом Flags - PullRequest
2 голосов
/ 02 февраля 2011

Возможно ли сериализовать System.Web.SessionState.SessionStateItemCollection с использованием protobuf-net? При попытке сериализации возникает следующее исключение:

Только классы контрактов данных (и списки / массивы таких) могут быть обработаны (обработка ошибок SessionStateItemCollection)

Что мне нужно сделать, чтобы сериализовать это?

1 Ответ

1 голос
/ 02 февраля 2011

Я не думаю, что это имеет какое-либо отношение к [Flags], если только вы не видите что-то еще ...

protobuf-net сериализует объекты в соответствии со спецификацией protobuf, определенной google, котораяпортативный формат, который требует, чтобы получатель заранее знал расположение конкретных данных - под этим я подразумеваю, что (в отличие от BinaryFormatter) это не включает в себя что-либо, чтобы сказать "этот объект MyCorp.Something.Customer из MyCorp.Something.dll ".Этот подход «не храните то, чем объект был » также распространен в json (JavaScriptSerializer), xml (XmlSerializer), DataContractSerializer и т. Д.

Так почемуэто имеет значение?Это важно, потому что в состоянии сеанса хранится произвольных объектов , которые невозможно предсказать.Действительно, нет никакой гарантии (особенно, если состояние всегда сохранялось в памяти), что объекты могут быть даже удаленно сериализуемыми по любой схеме.

Но это зависито том, что ваша цель;если вы хотите реализовать провайдер состояния сеанса , тогда это должно быть возможно - но вам просто нужно включить эти дополнительные метаданные в ваш провайдер, как я делал, когда писал провайдера кэша .Таким образом, это будет:

  • сериализация:
    • каким-либо образом кодировать GetType() метаданные
    • использовать Serialzier.NonGeneric для кодирования объекта (при условии, что он сериализуем)by protobuf-net)
  • десериализация
    • декодировать метаданные типа и разрешить ваше Type
    • использование Serializer.NonGeneric для декодирования объекта

Другой альтернативный подход заключается в простом использовании BinaryFormatter, который обрабатывает метаданные типа внутри , но перехватывает ISerializable для ваших специальных типов и передает его наProtobuf-сеть.Это позволяет обрабатывать ваши объекты бок о бок с объектами, которые не совместимы с protobuf-net, но получают расширенную сериализацию для ваших объектов.Краткий пример прокси ISerializable будет просто:

// these are the 2 methods used by ISerializable
protected YourType(SerializationInfo info, StreamingContext context)
{ // ctor, used for deserialization
    Serializer.Merge(info, this);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{ // used for serialization
    Serializer.Serialize(info, this);
}
...