使用MessagePack-CSharp序列化第三方继承类的属性配置问题求助
解决MessagePack-CSharp第三方父类成员序列化报错问题
当第三方DLL中的父类成员未标记KeyAttribute或IgnoreMemberAttribute,导致序列化报错c# MessagePack all public members must mark KeyAttribute or IgnoreMemberAttribute. MyTypmember:Id时,不用逐个重写成员,有以下几种类似AutoMapper配置式的解决方案:
1. 自定义类型契约解析器
通过实现自定义的IFormatterResolver和IMessagePackFormatter,为第三方父类指定序列化规则,无需修改原类代码:
// 自定义解析器,关联第三方父类的格式化器 public class ThirdPartyBaseClassResolver : IFormatterResolver { public IMessagePackFormatter<T>? GetFormatter<T>() { return typeof(T) == typeof(ThirdPartyBaseClass) ? (IMessagePackFormatter<T>)new ThirdPartyBaseClassFormatter() : null; } } // 实现第三方父类的序列化/反序列化逻辑 public class ThirdPartyBaseClassFormatter : IMessagePackFormatter<ThirdPartyBaseClass> { public void Serialize(ref MessagePackWriter writer, ThirdPartyBaseClass value, MessagePackSerializerOptions options) { // 写入映射头,数量对应要序列化的成员数 writer.WriteMapHeader(1); // 指定成员名称和Key(这里用名称当Key,也可以用数字) writer.Write(nameof(ThirdPartyBaseClass.Id)); writer.Write(value.Id); // 其他需要序列化的成员依次添加 } public ThirdPartyBaseClass Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { var mapCount = reader.ReadMapHeader(); var id = default(int); while (reader.ReadKey()) { var key = reader.ReadString(); if (key == nameof(ThirdPartyBaseClass.Id)) { id = reader.ReadInt32(); } else { reader.Skip(); // 跳过未知成员 } } // 实例化第三方类(注意:若类无无参构造,需用其他方式创建实例) var instance = Activator.CreateInstance<ThirdPartyBaseClass>(); instance.Id = id; return instance; } } // 使用配置序列化 var options = MessagePackSerializerOptions.Standard .WithResolver(new CompositeResolver( new ThirdPartyBaseClassResolver(), StandardResolver.Instance)); var serializedBytes = MessagePackSerializer.Serialize(yourModelInstance, options);
2. 用ContractlessStandardResolver快速兼容
如果不需要严格的Key映射,只是想序列化所有公共成员,可以直接使用内置的ContractlessStandardResolver,它会自动处理所有公共成员,无需标记属性:
var options = MessagePackSerializerOptions.Standard.WithResolver(ContractlessStandardResolver.Instance); var serializedBytes = MessagePackSerializer.Serialize(yourModelInstance, options);
注意:这种方式依赖成员名称和顺序,若第三方类后续修改成员,可能导致反序列化失败,适合内部系统或兼容性要求低的场景。
3. 使用Mixin特性附加属性标记
通过MixinAttribute为第三方类关联一个带有KeyAttribute的“影子类”,相当于给原类附加序列化标记:
// 创建Mixin类,成员名称、类型需与第三方父类完全匹配,并标记KeyAttribute [Mixin(typeof(ThirdPartyBaseClass))] public class ThirdPartyBaseClassMixin { [Key(0)] public int Id { get; set; } // 其他需要序列化的成员同理添加 } // 注册Mixin到解析器 var options = MessagePackSerializerOptions.Standard .WithResolver(new CompositeResolver( new MixinResolver(), StandardResolver.Instance)); // 正常序列化即可 var serializedBytes = MessagePackSerializer.Serialize(yourModelInstance, options);
内容的提问来源于stack exchange,提问作者pantonis
相关产品推荐
相关产品推荐

