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

2023-09-03 00:42:13 作者:怪我不能满足你

我有一个已经序列化的数据。与序列化的数据相关的类别是一个大的传统​​项目,有很多的一些并不需要为这个核心数据集第三方引用的一部分。现在我有一个需要读取该数据到另一个应用程序。我想重构出数据类成可在2个应用程序之间共享,所以我不最终需要所有的第三方库一个单独的项目。我也想保持与这一直是previously保存数据的兼容性。我并不需要改变任何字段中的类,就在项目它们位于何处。

I have data that's been serialized. The classes associated with the serialized data is part of a large legacy project which has a number of 3rd party references which are not needed for this core set of data. Now I have a need to read this data into another application. I'd like to refactor out the data classes into a separate project which can be shared between the 2 application so I don't end up needing all the 3rd party libraries. I also want to maintain compatibility with data that's been previously saved. I don't need to change any fields in the classes, just the project where they are located.

到目前为止,我搬到了类新项目。我已经把命名空间相同,因为他们在旧项目。但是,这并没有被充分读对象。我得到一个SerializationException指出解析错误,没有与XML密钥A1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp相关类型。纵观生成的SOAP XML,引用的模式已经改变。例如,我有一个类 MyCorp.Dashboard.DatabaseRoot 最初是在项目的 DashboardLibrary 。这被转移到项目的 DashboardData (但仍在使用的命名空间的 MyCorp.Dashboard.DatabaseRoot )。以这种方式更改的XML:

So far, I've moved the classes to a new project. I've kept the namespaces the same as they were in the old project. But, this hasn't been sufficient to read the objects. I get a SerializationException stating "Parse Error, no type associated with Xml key a1 MyCorp.MyApp.DatabaseRoot MyCorp.MyApp". Looking at the SOAP generated XML, the schemas referenced have changed. For example, I have a class MyCorp.Dashboard.DatabaseRoot originally in project DashboardLibrary. This was moved to project DashboardData (but still using namespace MyCorp.Dashboard.DatabaseRoot). The XML changed in this way:

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">

所以,我的问题是

So, my questions are

是否可以将类,并保持兼容性如何?我似乎已接近拉它关闭。 如果是这样,我怎么控制的最后一位模式信息(MyCorp.Dashboard与DashboardData)。原来似乎基于目录的位置,而第二个是项目名称。我试着改变的目录结构中的新项目,但有没有运气。别的我失踪?

感谢。

推荐答案

您需要实现一个自定义的 SerializationBinder 。重写 BindToType 方法来选择类型以读取根据其名称:

You need to implement a custom SerializationBinder. Override the BindToType method to select the type to load based on its name:

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;
}

(这是一个非常基本的实现,在真实的场景中,你可能会使用一个更好的映射逻辑)。

(this is a very basic implementation, in a real-world scenario you would probably use a better mapping logic).

您也可以覆盖 BindToName 如果需要reserialize数据,以便它仍然可以通过旧的组件读取。这允许您自定义序列化对象的组装和类型名称。

You can also override BindToName if you need to reserialize the data so that it can still be read by the old assembly. This allows you to customize the assembly and type name of the serialized object.

一旦你有你的自定义 SerializationBinder ,只需将其分配给 文件夹 格式化的财产,并用它通常是从那里。

Once you have your custom SerializationBinder, you just need to assign it to the Binder property of the formatter, and use it normally from there.

如果您需要更改类型的结构(增加或重命名字段,变更类型...),你将需​​要实施 ISerializationSurrogate 旧数据映射到新结构类型。

If you need to change the structure of the types (add or rename fields, change types...), you will need to implement a ISerializationSurrogate to map the old data to the new type structure.

 
精彩推荐
图片推荐