views:

215

answers:

2

I am using the following methods to serialize and deserialize .NET objects:

public static string SerializeToBase64(object data)
{
    var stream = new MemoryStream();
    var formatter = new BinaryFormatter();
    formatter.Serialize(stream, data);
    stream.Position = 0;
    return Convert.ToBase64String(stream.ToArray());
}

public static object DeserializeFromBase64(string data)
{
    var stream = new MemoryStream(Convert.FromBase64String(data));
    stream.Position = 0;
    var formatter = new BinaryFormatter();
    return formatter.Deserialize(stream);
}

These methods seem to work fine when working with simple classes marked with the [Serializable] attribute.

But I need to use this code to serialize entity classes (also maked as Serializable) created by an ORM framework, whereby each entity class is derived from a base class for which I do not have source code.

When working with instances of an entity class, it completes serialization without exceptions, but deserialization always throws a null reference exception when excecuting formatter.Deserialize().

I am not very familiar with the process of serialization, but I assume this problem must be caused by something anomalous in the state of the target object. Is there a standard set of criteria that an object must meet before serialization?

Any other debugging suggestions would be appreciated.

Thanks, Tim

UPDATE:

After further experimentation, I think I have discovered the cause of the problem. The target object has events that are handled by another class that is not marked as serializable, as described in this post.

What's interesting is that serialaztion works correctly, even with the event handlers attached - it's deserialization that fails.

But I have tested by temporarily removing the event handlers and both serialization and deserialization works correctly, so I assume this is the problem. However, since I don't have access to the code in which the events are declared, I can't immediately see how to implement the solution described above. It may be that I have to modify my serialization process to remove and then reinstate the event handlers.

+1  A: 

Which ORM framework is it? Note that ORM-generated types tend to be particularly obnoxious when used with BinaryFormatter, since they aren't always "POCO": they often have fields that relate to the ORM - so creating them standalone has issues. In short, I'm not hugely surprised that it doesn't work in this case.

You might want to consider using something like DataContractSerializer, XmlSerializer, protobuf-net, or maybe NetDataContractSerializer - these all do a similar job, but because they work on public properties (rather than fields) they tend to be more effective - and indeed many have inbuilt support for these approaches for use as a DTO.

Marc Gravell
I am using LightSpeed and, yes, their documentation tends to favour DataContractSerializer. However, I tried that and it also chokes on my sample scenario, so I think I definitely need to fix the event issue, as described in the update above.
Tim Coulter
A: 

Can you use Reflector on the ORM base class assembly? There could be some custom deserialization code which is causing the exception (i.e. it implements the ISerializable interface). If you can find out of that is the case, and what it is doing, you might be able to set enough state in the subclass' instance to keep it from happening. On the other hand, if it has a bug, then you're a bit out of luck.

Jesse C. Slicer
Thanks - great suggestion. In fact, I checked the docs and the base class hierarchy doesn't implement ISerializable, but it seems my problem is more fundamental (see update above).
Tim Coulter