C# WinForm序列化文件在ASP.NET反序列化时PublicKeyToken=null未找到问题
嘿,我来帮你搞定这个BinaryFormatter反序列化的问题!
错误含义解释
The assembly 'myApplication, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' was not found.
这个错误的核心意思是:你的ASP.NET应用在尝试反序列化AGENTI.bin文件时,找不到序列化这个文件时用来定义AGENTI类的那个程序集——也就是你的WinForm项目生成的myApplication程序集。
BinaryFormatter的特性就是会把对象的完整类型元数据(包括所属程序集的名称、版本、公钥令牌等)写入到序列化文件中,反序列化时必须找到完全匹配的程序集,才能重建出原本的对象。你之前在ASP.NET里序列化没问题,是因为当时AGENTI类属于ASP.NET项目自身的程序集;迁移到WinForm后,AGENTI类归属到了WinForm的程序集里,所以序列化后的二进制文件里记录的是WinForm程序集的信息,ASP.NET服务器上没有这个程序集,自然就报错了。从你提供的AGENTI.bin片段也能看出来,类型信息里已经关联了WinForm相关的程序集标识。
解决方案
1. 最推荐:共享实体类库(从根源解决问题)
这是最规范、最易维护的方案,把需要跨项目序列化/反序列化的实体类抽出来放到独立的类库中:
- 新建一个**.NET Framework 4.5类库项目**(比如命名为
MySharedEntities)。 - 把WinForm项目里的
AGENTI类移动到这个类库中,确保类的访问修饰符是public。 - 在WinForm项目和ASP.NET项目中都添加对这个类库的引用。
- 重新编译WinForm项目,生成新的序列化二进制文件,再传输到ASP.NET服务器上进行反序列化。
这样两边的AGENTI类都属于同一个共享程序集,序列化和反序列化时的程序集信息完全匹配,就不会再出现找不到程序集的问题。
2. 临时应急:给ASP.NET添加WinForm程序集引用
如果暂时不想重构代码,可以把WinForm项目生成的myApplication.dll复制到ASP.NET项目的bin目录下,或者直接在ASP.NET项目中引用WinForm项目。不过这种方式不推荐,因为WinForm程序集包含很多ASP.NET不需要的UI代码,会增加部署体积,后续版本更新也容易出冲突。
3. 自定义序列化绑定器(适配不同程序集)
如果上面两种方式都无法实现,可以通过自定义SerializationBinder来映射类型,让ASP.NET把WinForm程序集的类型映射到自身项目中相同结构的AGENTI类上:
- 首先定义一个自定义绑定器:
public class CustomSerializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { // 检测到WinForm程序集的标识时,替换为当前ASP.NET程序集的名称 if (assemblyName.StartsWith("myApplication,")) { assemblyName = System.Reflection.Assembly.GetExecutingAssembly().FullName; } return Type.GetType($"{typeName}, {assemblyName}"); } } - 然后在你的反序列化代码中设置这个绑定器:
注意:这种方式要求ASP.NET项目里的BinaryFormatter formatter = new BinaryFormatter(); formatter.Binder = new CustomSerializationBinder(); // 添加这一行AGENTI类和WinForm里的AGENTI类结构完全一致(字段、属性、类型都要一模一样),否则反序列化可能会出现数据丢失或异常。
内容的提问来源于stack exchange,提问作者MeJonata

