C#服务端序列化后客户端反序列化出现程序集找不到异常求助
解决BinaryFormatter反序列化找不到程序集的问题
你遇到的问题根源很明确:BinaryFormatter在序列化对象时,会把对象所属的Gateway程序集的完整标识(版本、公钥令牌等)写入序列化流里。客户端反序列化时必须找到这个程序集才能还原对象,但客户端环境里没有它,所以抛出了找不到程序集的异常。而且BinaryFormatter本身存在严重安全漏洞,微软早就不推荐在生产环境使用了。
下面给你几个可行的解决方案:
方案1:换用无程序集依赖的序列化方式(推荐)
优先用JSON序列化工具,比如System.Text.Json或者Newtonsoft.Json,这类工具只序列化对象的字段/属性数据,不会绑定具体程序集,跨平台兼容性也好。
服务端序列化代码(System.Text.Json)
using System.Text.Json; // 序列化对象为UTF-8字节数组 var jsonBytes = JsonSerializer.SerializeToUtf8Bytes(obj); return jsonBytes;
客户端反序列化代码
using System.Text.Json; // 把字节数组反序列化为目标类型 var targetObj = JsonSerializer.Deserialize<你的目标类型>(jsonBytes);
方案2:自定义程序集映射(仅在必须用BinaryFormatter时用)
如果一定要保留BinaryFormatter,可以在客户端实现SerializationBinder,把服务端的Gateway程序集映射到客户端对应的类型上:
客户端示例代码
using System.Runtime.Serialization; public class CustomAssemblyBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { // 匹配服务端的Gateway程序集,替换成客户端的程序集信息 if (assemblyName.StartsWith("Gateway,")) { // 这里替换成客户端中对应类型所在的程序集 assemblyName = typeof(你的客户端对应类型).Assembly.FullName; } return Type.GetType($"{typeName}, {assemblyName}"); } } // 反序列化时使用自定义Binder BinaryFormatter formatter = new BinaryFormatter(); formatter.Binder = new CustomAssemblyBinder(); using (MemoryStream ms = new MemoryStream(加密后的字节数组)) { var obj = formatter.Deserialize(ms); }
注意:这个方法要求客户端和服务端的类型结构完全一致,而且BinaryFormatter的安全风险依然存在,不推荐用于生产环境。
方案3:使用契约式序列化
用DataContractSerializer,它通过契约([DataContract]和[DataMember]标记)来序列化对象,可以脱离程序集依赖。
服务端配置与序列化代码
首先给你的数据类加契约标记:
using System.Runtime.Serialization; [DataContract] public class YourDataClass { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } }
然后序列化:
DataContractSerializer serializer = new DataContractSerializer(typeof(YourDataClass)); using (MemoryStream ms = new MemoryStream()) { serializer.WriteObject(ms, obj); return ms.ToArray(); }
客户端只要有结构一致且带相同契约标记的类型,就能正常反序列化,不需要依赖服务端的Gateway程序集。
内容的提问来源于stack exchange,提问作者Android Guy
相关产品推荐
相关产品推荐

