C# 如何让BinaryFormatter在不同的应用程序中反序列化

C# 如何让BinaryFormatter在不同的应用程序中反序列化,c#,.net,serialization,binaryformatter,C#,.net,Serialization,Binaryformatter,我正在使用BinaryFormatter将类实例数组序列化为文件。我可以在同一个应用程序中反序列化此罚款。当我在不同的应用程序中尝试相同的反序列化时(该应用程序拉入一个执行该工作的公共文件),我会得到以下错误: {"Could not load file or assembly 'pmlscan, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The module was ex

我正在使用BinaryFormatter将类实例数组序列化为文件。我可以在同一个应用程序中反序列化此罚款。当我在不同的应用程序中尝试相同的反序列化时(该应用程序拉入一个执行该工作的公共文件),我会得到以下错误:

{"Could not load file or assembly 'pmlscan, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The module was expected to contain an assembly manifest."}
其中,pmlscan是原始应用程序的名称。如何使BinaryFormatter不尝试加载pmlscan?

您不能


最好的选择是在单独的程序集中发布可序列化的类,并在服务器(序列化程序)和客户端(反序列化程序)中引用它。这样,您就不会将整个源代码发布到外部世界。

二进制序列化程序将类和程序集信息编码到二进制数组中。当您反序列化此数组时,反序列化器使用此信息定位类所在的程序集,并(如有必要)将程序集加载到您的应用程序域中。如果另一个应用程序没有访问类类型所在的程序集的权限,那么您将看到得到的错误


如另一张海报所述,将这些公共类放入共享程序集中,并将它们部署到客户端/其他应用程序以及服务器应用程序。

如果这些类相同,并且只是另一个程序集,则可以尝试向.config文件添加节

您还应该阅读关于和的文章

使用这些技术,您可以在反序列化时将.Net typesystem重定向到其他类型


注意:将共享类迁移到共享的.dll将是一个更简单的解决方案。

您可以通过使用自定义SerializationBinder来实现。请参见此处:

密封类PreMergeToMergedDeserializationBinder:SerializationBinder
{
公共重写类型BindToType(字符串assemblyName、字符串typeName)
{
返回Type.GetType(“BinarySerialization.YourClass”);
}
}
BinaryFormatter bfDeserialize=新的BinaryFormatter();
bfDeserialize.Binder=新的PreMergeToMergedDeserializationBinder();
while(fsRead.Position

假设您有一个exe可以序列化“YourClass”中的数据,另一个exe可以反序列化YourClass对象。

那么,您总是可以解析为另一个程序集和兼容类型进行反序列化。这是可行的,但不是针对内心脆弱的人。你在这里说的是.Net。一切皆有可能。(虽然单独的程序集是最容易的)。问题不是尝试加载和失败。问题是“不要尝试加载pmlscan”。使用assemblyRedirect,您不会尝试加载pmlscan。但是说“你不能!”是不对的。既然这是一件复杂的事情,我原谅你,也没有投你反对票;-)你可以!我现在就做了,它就像一个符咒:)。(我使用活页夹)虽然那篇文章很好(感谢链接),但请注意,这个答案几乎是一个只包含链接的答案;如果这篇文章消失了,您能在答案中再添加一些内容吗?该链接现在不起作用。@shtse8 link updated另请参见:中的“重写程序集/类型信息”部分
sealed class PreMergeToMergedDeserializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        return Type.GetType("BinarySerialization.YourClass");
    }
}
BinaryFormatter bfDeserialize = new BinaryFormatter();
bfDeserialize.Binder = new PreMergeToMergedDeserializationBinder();
while (fsRead.Position < fsRead.Length)
{
    YourClass sibla = (YourClass)bfDeserialize.Deserialize(fsRead);
}