gpt4 book ai didi

c# - .Net 二进制反序列化

转载 作者:行者123 更新时间:2023-11-30 12:50:38 27 4
gpt4 key购买 nike

我正在使用 BinaryFormatter 反序列化来自另一个应用程序的文件。它们共享基础库,并且文件中序列化的大多数类型都是已知的。

然而,也有一些类型是完全未知的,没有可更新的匹配项。我希望能够放弃这些情况下的反序列化。

目前我使用的是用 SurrogateSelector 和 SerializationBinder 初始化的 BinaryFormatter,我用它来更新受最近版本中命名空间更改影响的类型。

var formatter = new BinaryFormatter
{
Context = streamingContext,
SurrogateSelector = ss,
Binder = new ProxiedRemappingSerializationBinder(),
FilterLevel = TypeFilterLevel.Low
};

try
{
var deserializedObject = formatter.Deserialize(contentsStream);
...
}

具体来说,当 .NET Framework 在内部尝试在已知接口(interface)的数组上设置值但具有未知值类型时,就会出现问题。我得到的异常是:“System.InvalidCastException:对象不能存储在这种类型的数组中。”

那么有什么方法可以让反序列化过程丢弃这些类型(并只保留空值)或者甚至以某种方式作用于 SerializationBinder 以防止出现此异常?

提前致谢

** 编辑 **

除了堆栈跟踪之外,错误是典型的 InvalidcastException。我在 .NET Framework 中调试,通过 BinaryFormatter、BinaryObjectReader 和 ObjectManager,但它在数组的修复阶段(当它为实例分配实际值时)失败。在 Array.cs 中中断,第 516 行,在 InternalSetValue(&elemref,value);是引发异常的地方。

我正在使用 Binder 在反序列化时将某些类型更改为我的应用程序知道的类型(该类型的更新版本),或更改为虚拟类。我明白为什么会发生异常,基本上它是试图在接口(interface)数组上设置不兼容的对象类型。

此类型是我动态生成的代理类型,用于保存类似于此实现的对象信息: http://holistictendencies.wordpress.com/2009/11/16/creating-proxies-in-for-round-tripping-unknown-objects-in-c-server-apps/所以,因为它没有实现数组接口(interface),所以它失败了。我只是希望引擎以某种方式丢弃这些案例。

最佳答案

我有一个类似的问题,我需要 BinaryFormatter.Deserialize() 一个我没有类型信息但想从该对象的属性中获取一些值的类。

当需要反序列化该对象时,.NET 抛出 SerializationException,提示未知程序集类型。

我通过创建一个具有我需要的属性(标记为可序列化)的自定义类来解决它,然后创建另一个继承自 SerializationBinder 的类:

public class MySerializationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (assemblyName.Contains("namespace I don't have") && typeName.Contains("type info I don't have"))
return typeof(MySubstitute);
return Type.GetType($"{typeName}, {assemblyName}");
}
}

[Serializable]
public class MySubstitute
{
public string Name { get; set; }
public string Title { get; set; }
}

请注意,如果它不是我正在寻找的类型,我将如何返回传入的内容。

然后当您创建 BinaryFormatter 时,将 Binder 属性设置为新的自定义 Binder 实例:

 using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter()
{
Binder = new MySerializationBinder ()
};
mySubstitute = (MySubstitute)bf.Deserialize(fs);
fs.Close();
}

关于c# - .Net 二进制反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8747331/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com