C#实现:如何将二进制字节数组写入XML的CData属性
解决IXmlSerializable类添加CDATA属性存储二进制数据的问题
首先得先指出你现有代码里的几个明显问题,不然根本跑不起来:
- 你的
test属性同时加了两个XmlElementAttribute,这会导致序列化冲突; - 属性的
get直接返回自身、set又赋值给自己,会造成无限循环栈溢出,必须改成用私有字段存储值。
接下来咱们针对IXmlSerializable的特性,手动实现CDATA的读写逻辑——因为IXmlSerializable是完全自定义序列化,特性的作用很有限,得自己在WriteXml和ReadXml里处理CDATA节点。
完整实现示例
首先定义你的CustomXML类,实现IXmlSerializable,同时处理二进制数据转Base64后存入CDATA:
using System; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; public class CustomXML : IXmlSerializable { // 私有字段存储二进制数据对应的Base64字符串 private string _binaryCData; // 对外暴露的二进制数据属性,自动转Base64 public byte[] BinaryProperty { get => string.IsNullOrEmpty(_binaryCData) ? Array.Empty<byte>() : Convert.FromBase64String(_binaryCData); set => _binaryCData = value == null ? string.Empty : Convert.ToBase64String(value); } // IXmlSerializable 接口实现:返回null表示使用默认架构 public XmlSchema GetSchema() => null; // 自定义XML读取逻辑:读取CDATA节点里的Base64字符串 public void ReadXml(XmlReader reader) { // 移动到元素内容 reader.ReadStartElement(); // 读取CDATA内容 if (reader.NodeType == XmlNodeType.CDATA) { _binaryCData = reader.Value; } // 移动到结束元素 reader.ReadEndElement(); } // 自定义XML写入逻辑:把Base64字符串写入CDATA节点 public void WriteXml(XmlWriter writer) { // 写入CDATA节点,内容是二进制转的Base64字符串 writer.WriteCData(_binaryCData); } }
你的调用代码修正
然后修改你原来的调用代码,注意避免之前的循环引用问题:
// 假设这是你的二进制数据 byte[] bAry = BinaryData; // 实例化CustomXML并赋值 var customXml = new CustomXML(); customXml.BinaryProperty = bAry; // 赋值给item的Property(假设item也是IXmlSerializable实现类) item.Property = customXml;
关键说明
- 为什么用Base64?二进制数据直接存XML会有大量不可打印字符,转Base64是常规的安全做法,你说暂不考虑字符问题,但这个步骤能避免绝大多数序列化异常;
IXmlSerializable的核心是ReadXml和WriteXml,完全由你控制节点的生成和读取,所以必须手动创建CDATA节点,而不是靠特性;- 如果你的
item类也是IXmlSerializable,记得在它的WriteXml里正确序列化Property属性,比如调用XmlSerializer来序列化CustomXML实例,或者直接写入对应的节点。
内容的提问来源于stack exchange,提问作者user9864738
相关产品推荐
相关产品推荐

