如何用YamlDotNet将byte[]序列化为行内数组格式?
解决YamlDotNet将byte[]序列化为行内数组的问题
要实现将byte[]序列化为[49,20,50]这种行内YAML数组格式,无需绕弯修改为字符串类型,以下是两种直接有效的方案:
方案一:用特性指定单个属性的序列化样式
保持模型的byte[]类型,通过YamlMember特性强制该属性使用行内流样式,这是最简洁的实现方式:
- 调整模型类,给目标属性添加特性:
using YamlDotNet.Serialization; public class Device { public string Name { get; set; } // 指定该属性采用行内流样式序列化 [YamlMember(Style = YamlStyle.Flow)] public byte[] Key { get; set; } }
- 正常执行序列化:
var device = new Device { Name = "device1", Key = new byte[] { 49, 20, 50 } }; var serializer = new SerializerBuilder().Build(); var yaml = serializer.Serialize(device);
生成的YAML结果完全符合预期:
device: name: device1 key: [49,20,50]
方案二:自定义类型转换器(适配全局或复杂场景)
如果需要全局统一处理byte[]的行内序列化,或者有更复杂的自定义逻辑,可以实现IYamlTypeConverter,直接生成YAML序列节点而非字符串:
- 实现自定义转换器:
using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; public class ByteArrayFlowConverter : IYamlTypeConverter { public bool Accepts(Type type) { return type == typeof(byte[]); } // 反序列化逻辑(按需实现) public object ReadYaml(IParser parser, Type type) { var sequenceStart = parser.Consume<SequenceStart>(); var bytes = new List<byte>(); while (!(parser.Current is SequenceEnd)) { bytes.Add(byte.Parse(parser.Consume<Scalar>().Value)); } parser.Consume<SequenceEnd>(); return bytes.ToArray(); } // 序列化时生成行内序列 public void WriteYaml(IEmitter emitter, object value, Type type) { var bytes = (byte[])value; // 标记序列为行内流样式 emitter.Emit(new SequenceStart(null, null, true, FlowStyle.Flow)); foreach (var b in bytes) { emitter.Emit(new Scalar(b.ToString())); } emitter.Emit(new SequenceEnd()); } }
- 注册转换器并执行序列化:
var device = new Device { Name = "device1", Key = new byte[] { 49, 20, 50 } }; var serializer = new SerializerBuilder() .WithTypeConverter(new ByteArrayFlowConverter()) .Build(); var yaml = serializer.Serialize(device);
之前方案的问题分析
- 直接使用
byte[]不配置样式:YamlDotNet默认会将数组序列化为多行列表(块样式),这是框架默认行为。 - 转成字符串自定义拼接:生成的是YAML字符串类型,会被自动加上单引号,不符合目标的数组类型要求。
内容的提问来源于stack exchange,提问作者Romer
相关产品推荐
相关产品推荐

