传入基类参数时反序列化派生类型:自定义Message类序列化异常
解决BinaryFormatter序列化/反序列化派生类丢失数据的问题
你遇到的问题很典型——当用BinaryFormatter处理继承自Message的TestMessage时,反序列化只能得到基类实例,派生类的OtherString属性直接丢失了。这是因为默认情况下,要么序列化时没有正确写入派生类的类型信息,要么反序列化时程序无法识别派生类的类型。下面给你一步步的解决方案:
1. 确保基类和派生类都标记[Serializable]
BinaryFormatter要求所有要序列化的类必须标记[Serializable]特性,基类和派生类都不能少。先修正你的类定义:
[Serializable] public class Message { public string Name { get; set; } } [Serializable] public class TestMessage : Message { public string OtherString { get; set; } }
2. 检查序列化/反序列化方法的实现
你的SerializeMessage方法如果是类似下面这样的,其实已经能正确写入TestMessage的类型信息了:
public byte[] SerializeMessage(Message message) { using (MemoryStream fs = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, message); return fs.ToArray(); } }
问题通常出在反序列化环节。如果你的反序列化方法是这样的,就能自动返回派生类实例:
public Message DeserializeMessage(byte[] data) { using (MemoryStream fs = new MemoryStream(data)) { BinaryFormatter formatter = new BinaryFormatter(); // 这里会根据序列化时写入的类型信息,自动实例化对应的派生类 return (Message)formatter.Deserialize(fs); } }
调用的时候,只需要把反序列化的结果强转为TestMessage即可:
// 序列化TestMessage实例 var testMsg = new TestMessage { Name = "Demo", OtherString = "Extra Data" }; byte[] serializedData = SerializeMessage(testMsg); // 反序列化并强转 var deserializedMsg = (TestMessage)DeserializeMessage(serializedData); // 此时deserializedMsg.OtherString应该能正确获取到"Extra Data"
3. 处理跨程序集的派生类情况
如果TestMessage和Message不在同一个程序集里,反序列化时可能找不到类型。这时候需要自定义SerializationBinder来指定类型映射:
public class CustomSerializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { // 根据实际的命名空间和类型名调整 if (typeName.Equals("YourNamespace.TestMessage")) { return typeof(TestMessage); } // 基类的类型映射 return typeof(Message); } }
然后在反序列化时绑定这个自定义Binder:
public Message DeserializeMessage(byte[] data) { using (MemoryStream fs = new MemoryStream(data)) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Binder = new CustomSerializationBinder(); return (Message)formatter.Deserialize(fs); } }
重要提醒
微软已经将BinaryFormatter标记为过时(Obsolete),因为它存在严重的安全漏洞(攻击者可以构造恶意数据触发代码执行)。如果你的项目是新开发的,建议使用更安全的序列化方案:
System.Text.Json:微软官方推荐的轻量、安全JSON序列化库Newtonsoft.Json:功能丰富的老牌JSON序列化库Protobuf-net:基于Protocol Buffers的高效二进制序列化库
内容的提问来源于stack exchange,提问作者user3953989
相关产品推荐
相关产品推荐

