【问题标题】:Sharing a serialized object between applications在应用程序之间共享序列化对象
【发布时间】:2026-01-04 10:15:02
【问题描述】:

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

找不到程序集 'WindowsFormsApplication6, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'。

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

【问题讨论】:

  • 如果您使用的是 .NET 二进制序列化,您实际上需要引用相同的底层类型(如来自同一个 DLL 的那个)。如果您还需要传输到不同的类型,则需要使用不同的序列化协议。
  • 您需要将序列化类的定义放入一个单独的类库程序集中,您可以从两个应用程序中引用该程序集(从而共享类定义)。

标签: c# serialization deserialization


【解决方案1】:

这是我目前的工作方式

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

【讨论】:

    【解决方案2】:

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

    我强烈建议使用不依赖于类型的序列化程序;比如XmlSerializer/DataContractSerializer/JSON.NET/ServiceStack的JsonSerializer,或者protobuf-net。所有这些都可以正常工作,但重要的是不会与你作对,有两种不同的方式:

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

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

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

    【讨论】:

    • 其他序列化程序是否允许您序列化存储的图像对象,如 system.drawing.bitmap?
    • @Andy 我会说你在那里解决了错误的问题。位图类是实现。您应该序列化的是作为实际图像有效负载的 byte[](可能是众所周知的格式)。大多数序列化程序可以处理一个字节[]
    【解决方案3】:

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

    【讨论】:

    • 很好的解决方案。请注意,这会产生紧密耦合,因为两个版本必须使用相同的引用程序集。您必须检查版本控制。
    最近更新 更多