6

在应用程序 1 中,我序列化和反序列化对象,它工作正常。但是,我想在应用程序 2 中反序列化来自应用程序 1 的对象。我将定义该对象的类添加到应用程序 2。当我尝试反序列化它时,出现此错误:

找不到程序集“WindowsFormsApplication6,版本=1.0.0.0,文化=中性,PublicKeyToken=null”。

那么如何在两个应用程序之间共享序列化对象呢?

4

3 回答 3

7

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

于 2013-05-08T09:38:26.397 回答
7

如果您使用BinaryFormatter,则它在数据中包含完整的类型名称,其中包括 DTO 所在的程序集(类型始终由其程序集定义)。这里的一个选择是创建一个单独的 DTO 库,您可以从每个库中引用它 - 但请注意,BinaryFormatter在版本控制方面仍然非常不可靠:我看到人们丢失数据,因为他们编辑了他们的 DTO 并且一切都停止了工作。

我强烈建议使用不依赖类型的序列化程序;例如,/// XmlSerializerServiceStack 的,或 protobuf-net。所有这些都可以正常工作,但重要的是不会以两种不同的方式与您对抗:DataContractSerializerJSON.NETJsonSerializer

  • 它们对版本控制非常友好
  • 他们不在乎您是否在程序集之间移动类型

即使这样为序列化类型维护一个单独的 DTO 程序集可能是最方便的,但这并不强迫您这样做。最终,由于这些序列化程序都乐于跨操作系统/跨版本/跨语言/跨 CPU 工作,“不同的程序集”这一事实在很大程度上是一个“嗯,随便”。

要点:BinaryFormatter可能很脆。除了飞行中的数据(例如,在两个AppDomain实例之间进行远程处理),我从不推荐它。我当然不会将它用于任何持续时间长的东西,因为我根本无法保证将来能够重新加载它。

于 2013-05-08T09:43:34.260 回答
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);
        }
    }
于 2019-07-24T03:32:43.740 回答