迁移到 MessagePack(二进制)
MessagePack 是一种紧凑二进制 serialization 格式,与 JSON 和 XML 相比,生成的消息更小。 开放源代码适用于 C# 的 MessagePack 库性能非常高,提供内置的超快速 LZ4 压缩,可得到更小的数据。 该格式在使用 DataContractSerializer
或库自己的特性来批注数据类型时,效果最佳。 它经过配置后可支持 AOT 环境、非公共类型和成员以及只读类型和成员。
在从 BinaryFormatter 迁移的过程中,适用于 C# 的 MessagePack 的某些行为和功能将值得注意,尤其是在无法更改或需要尽量减少更改序列化类型的 API 时。
默认情况下,仅公共类型是可序列化的。 仅当
StandardResolverAllowPrivate.Options
作为参数提供给MessagePackSerializer.Serialize
和MessagePackSerializer.Deserialize
方法时,才能序列化私有结构和内部结构以及类。MessagePack 要求使用
[MessagePackObject]
属性对每个可序列化类型进行批注。 可以使用 ContractlessStandardResolver 可以避免这种情况,但可能会导致将来版本控制出现问题。每个可序列化的非静态字段和属性都需要使用
[Key]
属性进行批注。 如果使用[MessagePackObject(keyAsPropertyName: true)]
属性批注类型,则成员不需要显式批注。 在这种情况下,若要忽略某些公共成员,请使用[IgnoreMember]
属性。若要序列化私有成员,请使用 StandardResolverAllowPrivate。
可以使用
System.Runtime.Serialization
批注代替 MessagePack 批注:使用[DataContract]
代替[MessagePackObject]
,使用[DataMember]
代替[Key]
,使用[IgnoreDataMember]
代替[IgnoreMember]
。 如果要避免在定义可序列化类型的库中依赖 MessagePack,这些批注会非常有用。它支持只读/不可变类型和成员。 序列化程序将尝试使用与参数列表最匹配的公共构造函数。 可以使用
[SerializationConstructor]
属性以显式方式指定构造函数。通过易于创作的自定义格式化程序,可支持任意类型的 Serialization。 这消除了对属性和特定构造函数或成员模式的所有要求。
序列化程序支持 .NET 基类库提供的最常用的内置类型和集合。 可以在官方文档中找到完整列表。它具有允许自定义的扩展点。
警告
MessagePack 具有允许在不限制类型的情况下反序列化数据的 API。 根据 MessagePack 安全说明,应避免使用这些 API。
警告
某些 MessagePack API 的行为可通过可变静态进行自定义,这意味着代码可能会因为同一进程、AssemblyLoadContext 或 AppDomain 中其他代码可能会执行的操作而成功或失败。 还可以通过引用 MessagePackAnalyzer 包并启用 MsgPack001 和 MsgPack002 分析器,来保持代码的复原能力,这些分析器会指出任何使用具有可更改行为的 API 的情况。