反序列化问题:从不同的程序版本反序列化时出错 [英] Deserialization problem: Error when deserializing from a different program version

查看:22
本文介绍了反序列化问题:从不同的程序版本反序列化时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在花了几个小时在互联网上搜索解决方案并尝试了一些之后,我终于决定自己发布我的问题.

I finally decided myself to post my problem, after a couple of hours spent searching the Internet for solutions and trying some.

[问题背景]

我正在开发一个将分两部分部署的应用程序:

I am developing an application which will be deployed in two parts:

  • 一个 XML Importer 工具:它的作用是加载/读取一个 xml 文件以填充一些数据结构,然后将这些数据结构序列化为二进制文件.
  • 最终用户应用程序:它将加载由 XML 导入程序生成的二进制文件,并对恢复的数据结构进行一些处理.

目前,我只将 XML 导入器用于这两个目的(这意味着我首先加载 xml 并将其保存为二进制文件,然后重新打开 XML 导入器并加载我的二进制文件).

For now, I only use the XML Importer for both purposes (meaning I first load the xml and save it to a binary file, then I reopen the XML Importer and load my binary file).

[实际问题]

这工作得很好,我能够在 XML 加载后恢复我拥有的所有数据,只要我使用相同的 XML 导入程序构建.这是不可行的,因为我至少需要两种不同的构建,一种用于 XML 导入程序,一种用于最终用户应用程序.请注意,我用于测试的两个版本的 XML 导入器在源代码和数据结构方面完全相同,唯一的区别在于内部版本号(为了强制使用不同的版本,我只需在某处添加一个空格并重新构建).

This works just fine and I am able to recover all the data I had after XML loading, as long as I do that with the same build of my XML Importer. This is not viable, as I will need at the very least two different builds, one for the XML Importer and one for the end user application. Please note that the two versions of the XML Importer I use for my testing are exactly the same concerning the source code and thus the datastructures, the only difference lies in the build number (to force a different build I just add a space somewhere and build again).

所以我想做的是:

  • 构建我的 XML 导入器的一个版本
  • 打开 XML 导入器,加载 XML 文件并将生成的数据结构保存到二进制文件中
  • 重建 XML 导入器
  • 打开新建的 XML 导入器,加载之前创建的二进制文件并恢复我的数据结构.

此时,我得到一个异常:

At this time, I get an Exception:

SerializationException: Could not find type 'System.Collections.Generic.List`1[[Grid, 74b7fa2fcc11e47f8bc966e9110610a6, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'.
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadType (System.IO.BinaryReader reader, TypeTag code)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadTypeMetadata (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectInstance (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info)

为了您的信息(不知道是否有用),它正在努力反序列化的实际类型是列表,网格是自定义类(可以正确序列化,因为我在使用相同版本的 XML 导入器).

For your information (don't know if useful or not), the actual type it is struggling to deserialize is a List, Grid being a custom Class (which is correctly serializable, as I am able to do it when using the same version of XML Importer).

[潜在解决方案]

我确实相信它来自大会的某个地方,因为我阅读了许多关于此的帖子和文章.但是,我已经有一个自定义 Binder 来处理程序集名称的差异,如下所示:

I do believe it comes from somewhere around the Assembly, as I read many posts and articles about this. However, I already have a custom Binder taking care of the differences of Assembly names, looking like this:

public sealed class VersionDeserializationBinder : SerializationBinder
{ 
    public override Type BindToType( string assemblyName, string typeName )
    { 
        if ( !string.IsNullOrEmpty( assemblyName ) && !string.IsNullOrEmpty( typeName ) )
        { 
            Type typeToDeserialize = null; 
            assemblyName = Assembly.GetExecutingAssembly().FullName; 
            // The following line of code returns the type. 
            typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) ); 

            return typeToDeserialize; 
        } 

        return null; 
    }
}

在此处反序列化之前分配给 BinaryFormatter:

which I assign to the BinaryFormatter before deserializing here:

    public static SaveData Load (string filePath) 
    {
        SaveData data = null;//new SaveData ();
        Stream stream;

        stream = File.Open(filePath, FileMode.Open);


        BinaryFormatter bformatter = new BinaryFormatter();
        bformatter.Binder = new VersionDeserializationBinder(); 
        data = (SaveData)bformatter.Deserialize(stream);
        stream.Close();

        Debug.Log("Binary version loaded from " + filePath);

        return data; 
    }

你们有没有人知道我该如何修复它?会很棒,很漂亮:)

Do any of you guys have an idea on how I could fix it? Would be awesome, pretty please :)

推荐答案

将工作位移动到单独的程序集并在服务器"和客户端"中使用该程序集.根据您对问题的解释,如果这是核心问题,这应该可以解决错误版本"问题.我还会将任何模型"(即像网格这样的状态位)带到域模型项目中,并在两个地方使用它.

Move the working bits to a separate assembly and use the assembly in both "server" and "client". Based on your explanation of the problem, this should get around the "wrong version" problem, if that is the core issue. I would also take any "models" (i.e. bits of state like Grid) to a domain model project, and use that in both places.

这篇关于反序列化问题:从不同的程序版本反序列化时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆