移动类时保持.NET序列化数据的兼容性

移动类时保持.NET序列化数据的兼容性,.net,serialization,soap,.net,Serialization,Soap,我有已经序列化的数据。与序列化数据相关联的类是大型遗留项目的一部分,该项目有许多第三方引用,而这些第三方引用不是此核心数据集所需的。现在我需要将这些数据读入另一个应用程序。我想把数据类重构成一个单独的项目,可以在2个应用程序之间共享,这样我就不需要所有的第三方库了。我还想保持与以前保存的数据的兼容性。我不需要更改类中的任何字段,只需要更改它们所在的项目 到目前为止,我已经将这些课程转移到一个新项目中。我保持名称空间与旧项目中的名称空间相同。但是,这还不足以读取对象。我得到一个Serializat

我有已经序列化的数据。与序列化数据相关联的类是大型遗留项目的一部分,该项目有许多第三方引用,而这些第三方引用不是此核心数据集所需的。现在我需要将这些数据读入另一个应用程序。我想把数据类重构成一个单独的项目,可以在2个应用程序之间共享,这样我就不需要所有的第三方库了。我还想保持与以前保存的数据的兼容性。我不需要更改类中的任何字段,只需要更改它们所在的项目

到目前为止,我已经将这些课程转移到一个新项目中。我保持名称空间与旧项目中的名称空间相同。但是,这还不足以读取对象。我得到一个SerializationException,声明“解析错误,没有与Xml键a1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp关联的类型”。查看SOAP生成的XML,所引用的模式已经更改。例如,我有一个类MyCorp.Dashboard.DatabaseRoot,它最初位于项目DashboardLibrary中。这已移动到projectDashboardData(但仍使用命名空间MyCorp.Dashboard.DatabaseRoot)。XML以这种方式更改:

Orig: <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/MyCorp.Dashboard">
New:  <a1:DatabaseRoot id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MyCorp.Dashboard/DashboardData">
Orig:
新的:
所以,我的问题是

  • 是否可以移动类并保持兼容性?我似乎快要成功了
  • 如果是,我如何控制最后一位模式信息(MyCorp.Dashboard与DashboardData)。原始的似乎是基于目录位置,而第二个是项目名称。我曾尝试在新项目中更改目录结构,但没有成功。我还缺什么

谢谢。

您需要实现自定义。重写该方法以根据其名称选择要加载的类型:

public override Type BindToType(string assemblyName, string typeName)
{
    if (assemblyName == "MyOldAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    {
        if (typeName == "MyOldNamespace.MyOldClass")
        {
            return typeof(MyNewClass);
        }
    }
    // Fall back to the default behavior, which will throw
    // a SerializationException if the old assembly can't be found
    return null;
}
(这是一个非常基本的实现,在真实场景中,您可能会使用更好的映射逻辑)

如果需要重新序列化数据,以便旧程序集仍可读取数据,也可以重写。这允许您自定义序列化对象的程序集和类型名称

一旦有了自定义的
SerializationBinder
,您只需将其分配给格式化程序的属性,并从此处开始正常使用它


如果需要更改类型的结构(添加或重命名字段、更改类型…),则需要实现将旧数据映射到新类型结构的方法。

使用哪个序列化程序?这是关键…System.Runtime.Serialization.Formatters.Soap.SoapFormatter可能,编写一个程序从旧源读取并以新格式写入?这是可能的,但我希望对运行它的人透明。