在应用程序 1 中,我序列化和反序列化对象,它工作正常。但是,我想在应用程序 2 中反序列化来自应用程序 1 的对象。我将定义该对象的类添加到应用程序 2。当我尝试反序列化它时,出现此错误:
找不到程序集“WindowsFormsApplication6,版本=1.0.0.0,文化=中性,PublicKeyToken=null”。
那么如何在两个应用程序之间共享序列化对象呢?
在应用程序 1 中,我序列化和反序列化对象,它工作正常。但是,我想在应用程序 2 中反序列化来自应用程序 1 的对象。我将定义该对象的类添加到应用程序 2。当我尝试反序列化它时,出现此错误:
找不到程序集“WindowsFormsApplication6,版本=1.0.0.0,文化=中性,PublicKeyToken=null”。
那么如何在两个应用程序之间共享序列化对象呢?
将可序列化对象的定义放入单独的程序集中,然后将对共享程序集的引用添加到每个项目。(格式化程序在您的第一个项目中添加对程序集的引用 - 它们实际上必须引用同一个类,而不仅仅是该类的相同副本)
如果您使用BinaryFormatter
,则它在数据中包含完整的类型名称,其中包括 DTO 所在的程序集(类型始终由其程序集定义)。这里的一个选择是创建一个单独的 DTO 库,您可以从每个库中引用它 - 但请注意,BinaryFormatter
在版本控制方面仍然非常不可靠:我看到人们丢失数据,因为他们编辑了他们的 DTO 并且一切都停止了工作。
我强烈建议使用不依赖类型的序列化程序;例如,/// XmlSerializer
ServiceStack 的,或 protobuf-net。所有这些都可以正常工作,但重要的是不会以两种不同的方式与您对抗:DataContractSerializer
JSON.NET
JsonSerializer
即使这样,为序列化类型维护一个单独的 DTO 程序集可能是最方便的,但这并不强迫您这样做。最终,由于这些序列化程序都乐于跨操作系统/跨版本/跨语言/跨 CPU 工作,“不同的程序集”这一事实在很大程度上是一个“嗯,随便”。
要点:BinaryFormatter
可能很脆。除了飞行中的数据(例如,在两个AppDomain
实例之间进行远程处理),我从不推荐它。我当然不会将它用于任何持续时间长的东西,因为我根本无法保证将来能够重新加载它。
这是我目前的工作方式
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);
}
}