You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不同.NET版本下BinaryFormatter序列化同一对象结果不一致问题

问题原因

字节数组不一致的核心原因是你使用了BinaryFormatter做序列化,这个类从设计层面就不支持跨运行时版本、跨进程的序列化兼容,且微软早已将其标记为存在严重安全风险的废弃组件,明确禁止在网络传输等跨边界场景使用。
你当前服务端运行在.NET 5,客户端运行在.NET 6,两个版本的核心运行时程序集版本、类型元数据生成规则、BinaryFormatter内部序列化逻辑均存在差异:BinaryFormatter序列化时会将类型所属的完整程序集信息、运行时相关的元数据全部写入字节流,即便你自定义的Message类代码完全一致,两端生成的序列化结果也会因为框架版本差异出现长度、内容不一致的问题,自然无法跨端反序列化。

修复方案

立即弃用BinaryFormatter,替换为跨版本、跨平台兼容的标准化序列化格式,以下是两种适用于IM场景的常用方案:

方案1:使用内置System.Text.Json(零额外依赖,实现最简单)

该方案是.NET生态下跨端传输的首选,无需引入第三方依赖,只要两端统一序列化规则即可保证结果一致,后续甚至支持非.NET客户端对接。

  1. 移除Message类上的[Serializable]特性,该特性仅为BinaryFormatter等老旧序列化器设计,JSON序列化不需要
  2. 将序列化/反序列化逻辑替换为以下实现:
// 对象转字节数组
public static byte[] ObjectToBytes<T>(T obj)
{
    return JsonSerializer.SerializeToUtf8Bytes(obj, new JsonSerializerOptions
    {
        // 两端保持相同的配置规则即可
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    });
}

// 字节数组转对象
public static T BytesToObject<T>(byte[] data)
{
    return JsonSerializer.Deserialize<T>(data, new JsonSerializerOptions
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    });
}

方案2:使用Protobuf二进制序列化(高性能、小体积,适合高频消息场景)

如果你的IM应用消息传输频率高,对序列化性能、消息包体积有更高要求,可以选择Protobuf格式,它是跨语言兼容的标准化二进制序列化协议,序列化速度比JSON快数倍,生成的消息体积也更小。
你可以选择官方Google.Protobuf库,或者使用更适配现有C#类写法的protobuf-net库,按照库文档给类添加对应序列化标记后,即可实现跨版本一致的序列化/反序列化。

重要提示:不要尝试通过修改BinaryFormatter绑定配置、强行对齐两端程序集版本的方式临时修复问题,这种方式不仅维护成本极高,后续任意一端升级.NET版本就会再次失效,还会面临BinaryFormatter自带的远程代码执行安全漏洞风险。

内容的提问来源于stack exchange,提问作者Mamink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:57:25