C#BinaryFormatter - 使用另一个命名空间中的对象反序列化

J4N*_*J4N 9 .net c# binary serialization

最近,我们将部分代码移到了不同​​的项目库中.

不幸的是,似乎这些数据已被序列化到数据库中BinaryFormatter(不要问我为什么,我不知道,我讨厌这个想法).

现在我负责创建一个更新数据库的更新工具(当我们的软件根据版本检测到需要更新的数据库时,我们的软件会自动启动该工具):

  1. 创建新列
  2. 反序列化二进制列
  3. 将反序列化的列写入新列
  4. 删除旧的二进制列

我的问题是,当我尝试反序列化时,它告诉我:

Unable to find assembly 'MyOldAssemblyName, Version=2.0.0.0, Culture=neutral, PublicKeyToken=a5b9cb7043cc16da'.
Run Code Online (Sandbox Code Playgroud)

但是这个组件不再存在了.我把这个类放在我的"更新程序"项目中没有问题,但我无法保持这个旧项目只包含这个文件.

有没有办法指定BinaryFormatter它必须反序列化它用指定类接收的Stream?

或者说组件已重命名,或???

Mar*_*ell 7

要告诉它该类型已在程序集之间移动(但它保留了旧名称和命名空间),您有时可以使用(在程序集中)[assembly:TypeForwardedTo(typeof(TheType))]. 这里的“有时”是因为您需要使用typeof,这意味着您需要从旧程序集到新程序集的引用,这并不总是可能的 - 但通常是(尤其是当您从 UI 层移动类型时下降到 POCO/DTO 层,因为 UI 通常引用 POCO/DTO)。

但是,如果您重命名了已更改命名空间的类型,则需要您编写自定义“绑定器”(请参阅此处)。

应该注意的是,BinaryFormatter它本质上是一个基于类型的序列化器,在版本化或重构代码时总会遇到很多问题。如果类型不是“写一次,然后永远不要改变它”,那么我强烈建议使用更灵活的东西 -基于合同而不是基于类型的东西。基本上,除了BinaryFormatter(或NetDataContractSerializer)之外的任何东西:XmlSerializer, DataContractSerializer, protobuf-net, Json.NET 等都可以,并且不会在意您重新定位或重命名类型。


J4N*_*J4N 5

事实上,我认为我自己找到了解决方案。

我们可以为SerializationBinder二进制格式化程序提供 a ,这将允许我们手动解析在流中找到的类。

更多信息在这里