Exception when serializing enum values with Flags attribute
Is itpossible to serialize System.Web.SessionState.SessionStateItemCollection
using protobuf-net? The following exception occur while trying to serialize:
Only data-contract classes (and lists/arrays of such) can be proces开发者_如何学Gosed (error processing SessionStateItemCollection)
What do I need to do to serialize this?
I don't think this has anything to do with [Flags]
, unless you are seeing something else...
protobuf-net serializes objects in accordance with the protobuf spec defined by google, which is a portable format that requires the receiever to know the layout of the specific data in advance - by which I mean that (unlike BinaryFormatter
) it doesn't include anything to say "this object is a MyCorp.Something.Customer
from MyCorp.Something.dll
". This "don't store what the object was" approach is also common to json (JavaScriptSerializer
), xml (XmlSerializer
), DataContractSerializer
, etc.
So why does this matter? It matters because session state is storing arbitrary objects that can't be predicted. Indeed, there is no guarantee (especially if the state has always been stored in memory) that the objects are even remotely serializable under any scheme.
But it depends on what your aim is; if you want to implement a session-state provider, then that should be possible - but you would just need to include this extra metadata in your provider, like I did when writing a cache provider. So it would be:
- serialization:
- encode the
GetType()
metadata in some way - use
Serialzier.NonGeneric
to encode the object (assuming it is serializable by protobuf-net)
- encode the
- deserialization
- decode the type metadata and resolve your
Type
- use
Serializer.NonGeneric
to decode the object
- decode the type metadata and resolve your
Another alternative approach would be to simply use BinaryFormatter
which handles the type metadata internally, but hook ISerializable
for your special types and forward that to protobuf-net. This allows your objects to be handled side-by-side with objects that aren't protobuf-net compatible, but get the enhanced serialization for your objects. A brief example of proxying ISerializable
would be simply:
// 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);
}
精彩评论