Reputation: 29498
I'm attempting to deserialize some objects using the BinaryFormatter where the serialized objects might contain unknown types, types that were serialized from assemblies that are not present in the deserializing application. In the case that the type is unknown, I would like to simply deserialize it as a null value.
I came across this thread on microsoft social which didn't bottom out on a solution. The thread links to this question which also doesn't have an answer, but is about xml, not binary formatting.
Upvotes: 1
Views: 1110
Reputation: 29498
This question probably could have been written with more detail, but I didn't really know where to start. I have since figured out the solution, so here are the details.
First, you must implement a SerializationBinder. In the BindToType
override, you are given the assembly name and type name as strings. When the assembly name is for an assembly that you don't know about, return a marker type that indicates it is unknown; I created a class UnknownType {}
for this purpose.
class UnknownType { }
class UnknownBinder : SerializationBinder
{
bool IsUnknown(string asmName)
{
// your impl here
throw new NotImplementedException();
}
public override Type BindToType(string assemblyName, string typeName)
{
if(IsUnknown(assemblyName))
{
return typeof(UnknownType);
}
return Type.GetType(typeName);
}
}
The second step is to implement an ISurrogateSelector and ISerializationSurrogate. These will be implemented to "return null" any time UnknownType
is encountered.
class UnknownSurrogateSelector : ISurrogateSelector, ISerializationSurrogate
{
public void ChainSelector(ISurrogateSelector selector)
{
}
public ISurrogateSelector GetNextSelector()
{
return null;
}
public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector)
{
if(type == typeof(UnknownType))
{
selector = this;
return this;
}
selector = null;
return null;
}
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
if (obj is UnknownType)
return null;
return obj;
}
}
The surrogate selector is attached to the SurrogateSelector member of the BinaryFormatter instance, and the binder is attached to the Binder member.
Upvotes: 3