使用 BinaryFormatter 反序列化未知类型的 .NET 对象
Deserialize a .NET object of unknown type with BinaryFormatter
我正在尝试使用 BinaryFormatter 反序列化一些对象,其中序列化的对象可能包含未知类型,这些类型是从反序列化应用程序中不存在的程序集中序列化的。在类型未知的情况下,我想简单地将其反序列化为空值。
我遇到了 this thread on microsoft social which didn't bottom out on a solution. The thread links to this question,它也没有答案,但关于 xml,而不是二进制格式。
这个问题本来可以写得更详细,但我真的不知道从哪里开始。我已经找到了解决方案,所以这里是详细信息。
首先,您必须实施 SerializationBinder。在 BindToType
覆盖中,您将以字符串形式获得程序集名称和类型名称。当程序集名称是您不知道的程序集时,return 表示未知的标记类型;我为此创建了一个 class UnknownType {}
。
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);
}
}
第二步是实现一个ISurrogateSelector and ISerializationSurrogate。每当遇到 UnknownType
时,这些将实施到 "return null"。
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;
}
}
代理选择器附加到 BinaryFormatter 实例的 SurrogateSelector 成员,活页夹附加到 Binder 成员。
我正在尝试使用 BinaryFormatter 反序列化一些对象,其中序列化的对象可能包含未知类型,这些类型是从反序列化应用程序中不存在的程序集中序列化的。在类型未知的情况下,我想简单地将其反序列化为空值。
我遇到了 this thread on microsoft social which didn't bottom out on a solution. The thread links to this question,它也没有答案,但关于 xml,而不是二进制格式。
这个问题本来可以写得更详细,但我真的不知道从哪里开始。我已经找到了解决方案,所以这里是详细信息。
首先,您必须实施 SerializationBinder。在 BindToType
覆盖中,您将以字符串形式获得程序集名称和类型名称。当程序集名称是您不知道的程序集时,return 表示未知的标记类型;我为此创建了一个 class UnknownType {}
。
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);
}
}
第二步是实现一个ISurrogateSelector and ISerializationSurrogate。每当遇到 UnknownType
时,这些将实施到 "return null"。
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;
}
}
代理选择器附加到 BinaryFormatter 实例的 SurrogateSelector 成员,活页夹附加到 Binder 成员。