在应用程序之间共享序列化对象

6
在应用程序1中,我对一个对象进行序列化和反序列化,并且它可以正常工作。然而,我想在应用程序2中反序列化应用程序1中的对象。我已经将定义该对象的类添加到应用程序2中。但是,当我尝试反序列化它时,会出现以下错误:
“找不到程序集 'WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'。”
那么,如何在两个应用程序之间共享序列化对象呢?

1
如果您正在使用.NET二进制序列化,您需要实际引用相同的基础类型(例如来自同一DLL的类型)。如果您还需要传输到不同的类型,则需要使用不同的序列化协议。 - Adam Houldsworth
2
你需要将序列化类的定义放入一个单独的类库程序集中,然后从两个应用程序中引用它(从而共享类定义)。 - Matthew Watson
3个回答

7
将可序列化对象的定义放入单独的程序集中,然后向每个项目添加对共享程序集的引用。(格式化程序正在向您的第一个项目中添加对该程序集的引用 - 实际上它们必须引用同一类,而不仅仅是相同的类副本)。

好的解决方案。请注意,这会创建紧密耦合,因为两个版本必须使用相同的引用程序集。您必须审查版本控制。 - Myrtle

7
如果您正在使用 BinaryFormatter ,那么它会在数据中包含完整的类型名称,其中包括DTO所在的程序集(类型总是由其程序集定义)。这里的一个选项是创建一个单独的DTO库,您可以从每个库中引用该库 - 但请注意, BinaryFormatter 在版本控制方面仍然相当不可靠:我看到过人们丢失数据,因为他们编辑了他们的DTO,然后一切都停止工作了。
我强烈建议使用非类型相关的序列化器;例如, XmlSerializer / DataContractSerializer / JSON.NET / ServiceStack的 JsonSerializer 或protobuf-net。所有这些都可以正常工作,但重要的是,它们不会以两种不同的方式与您作斗争:
  • 它们非常友好地支持版本控制
  • 如果您在不同的程序集之间移动类型,它们也不会介意
即使有了这个,最方便的方法可能还是维护一个单独的DTO程序集,用于序列化类型,但它并不强制执行。最终,由于这些序列化器都可以跨操作系统/跨版本/跨语言/跨CPU工作,因此“不同的程序集”这个事实非常重要。
关键点: BinaryFormatter 可能很脆弱。我从不推荐它用于任何事情,除了在传输数据时(例如,在两个 AppDomain 实例之间进行远程处理)。对于任何需要持续一段时间的内容,我肯定不会使用它,因为我根本不能保证将来能够重新加载它。

其他序列化器是否允许您像 System.Drawing.Bitmap 一样序列化存储的图像对象? - AndyD273
@Andy,我认为你正在解决错误的问题。位图类是实现细节。你应该序列化的是 byte[],它是实际图像负载(可能是以众所周知的格式)。大多数序列化程序都可以处理 byte[]。 - Marc Gravell

0

这是我目前的做法

    public sealed class VersionDeserializer : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            var assemVer1 = Assembly.GetExecutingAssembly().FullName;
            var deserializeType = Type.GetType(string.Format("{0}, {1}", typeName, assemVer1));

            return deserializeType;
        }
    }

    private object FromByteArray(byte[] data)
    {
        var bf = new BinaryFormatter
        {
            Binder = new VersionDeserializer()
        };

        using (MemoryStream ms = new MemoryStream(data))
        {
            return bf.Deserialize(ms);
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接