XmlSerializer,base64编码一个String成员

考虑一个简单的案例

public class Test { public String myString; } 

有什么办法可以告诉XmlSerializer在序列化时对base64编码myString吗?

您可以简单地将其设置为byte[]属性,它将自动对Base64进行编码:

 public class Test { public byte[] MyProperty {get;set;} public void SetMyProperty(string text) { MyProperty = System.Text.Encoding.Unicode.GetBytes(text); } } Test test = new Test(); test. SetMyProperty("123456789123456789"); 

输出:

 MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA 

(尝试解码)

遗憾的是,我无法(我知道)将MyProperty设为私有,并且仍然在System.Xml.Serialization进行序列化。

Base64将二进制数据转换为字符串。 如果要对字符串中的数据进行base64编码,则需要先将其编码为字节数组,例如使用Encoding.UTF.GetBytes(myString)

这提出了一个问题,为什么你最初想要做到这一点。 如果你需要使用base 64,你确定你真的有文本数据开始吗?

在Jon Grant有用的建议之后,我实现了一个封装所需Base64编码的Base64String类型。

 public class Base64String: IXmlSerializable { private string value; public Base64String() { } public Base64String(string value) { this.value = value; } public string Value { get { return value; } set { this.value = value; } } public static implicit operator string(Base64String x) { return x.ToString(); } public static implicit operator Base64String(string x) { return new Base64String(x); } public override string ToString() { return value; } #region IXmlSerializable Members public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(System.Xml.XmlReader reader) { MemoryStream ms = null; byte[] buffer = new byte[256]; int bytesRead; while ((bytesRead = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0) { if (ms == null) ms = new MemoryStream(bytesRead); ms.Write(buffer, 0, bytesRead); } if (ms != null) value = System.Text.UnicodeEncoding.Unicode.GetString(ms.ToArray()); } public void WriteXml(System.Xml.XmlWriter writer) { if (!string.IsNullOrEmpty(value)) { byte[] rawData = Encoding.Unicode.GetBytes(value); writer.WriteBase64(rawData, 0, rawData.Length); } } static public string EncodeTo64(string toEncode) { byte[] toEncodeAsBytes = System.Text.UnicodeEncoding.Unicode.GetBytes(toEncode); string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); return returnValue; } static public string DecodeFrom64(string encodedData) { byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData); string returnValue = System.Text.UnicodeEncoding.Unicode.GetString(encodedDataAsBytes); return returnValue; } #endregion } 

你可以使用这样的类型:

 static void Main(string[] args) { Foo foo = new Foo(); foo.Field1 = "Pluto"; foo.Field2 = "Pippo"; foo.Field3 = "Topolino"; foo.Field4 = "Paperino"; XmlSerializer ser = new XmlSerializer(typeof(Foo)); ser.Serialize(Console.Out, foo); Console.ReadLine(); } [XmlRoot("Sample")] public class Foo { public Foo() { } [XmlElement("Alfa_64")] public Base64String Field1; [XmlElement("Beta")] public string Field2; [XmlElement("Gamma_64")] public Base64String Field3; [XmlElement("Delta_64")] public Base64String Field4; } 

您将字符串存储为Base64值,然后具有在get子句中对其进行解码的属性。

XmlSerializer类更改输出的唯一受支持的方法(没有丑陋的黑客,如具有特殊的隐藏属性等)是实现IXmlSerializable接口。

通过定义实现IXmlSerializableBase64String类并只写出编码的字符串,您可以节省自己必须为整个类编写序列化代码。 定义一个运算符,使其可以隐式地转换为字符串,它应该像普通字符串一样工作。