XmlSerializer, base64 encoder un membre de chaîne

Considérons un cas simple

public class Test { public Ssortingng mySsortingng; } 

Est-il possible de dire à XmlSerializer de coder en base64 mySsortingng lors de sa sérialisation?

Vous pouvez simplement le définir comme propriété byte[] et il sera encodé automatiquement par Base64:

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

Sortie:

 MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA 

(Essayez de décoder cela ici )

Malheureusement, il n’ya aucun moyen (à ma connaissance) de rendre MyProperty privé tout en restant sérialisé dans System.Xml.Serialization .

Base64 convertit les données binarys en une chaîne. Si vous voulez encoder en base64 les données d’une chaîne, vous devez d’abord l’encoder sous forme de tableau d’octets, par exemple en utilisant Encoding.UTF.GetBytes(mySsortingng) .

Cela soulève la question de savoir pourquoi exactement vous voudriez le faire en premier lieu. Si vous devez utiliser la base 64, êtes-vous sûr de disposer de données texte pour commencer?

Suite à la suggestion utile de Jon Grant, j’ai implémenté un type Base64Ssortingng qui encapsule le codage Base64 requirejs.

 public class Base64Ssortingng: IXmlSerializable { private ssortingng value; public Base64Ssortingng() { } public Base64Ssortingng(ssortingng value) { this.value = value; } public ssortingng Value { get { return value; } set { this.value = value; } } public static implicit operator ssortingng(Base64Ssortingng x) { return x.ToSsortingng(); } public static implicit operator Base64Ssortingng(ssortingng x) { return new Base64Ssortingng(x); } public override ssortingng ToSsortingng() { 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.GetSsortingng(ms.ToArray()); } public void WriteXml(System.Xml.XmlWriter writer) { if (!ssortingng.IsNullOrEmpty(value)) { byte[] rawData = Encoding.Unicode.GetBytes(value); writer.WriteBase64(rawData, 0, rawData.Length); } } static public ssortingng EncodeTo64(ssortingng toEncode) { byte[] toEncodeAsBytes = System.Text.UnicodeEncoding.Unicode.GetBytes(toEncode); ssortingng returnValue = System.Convert.ToBase64Ssortingng(toEncodeAsBytes); return returnValue; } static public ssortingng DecodeFrom64(ssortingng encodedData) { byte[] encodedDataAsBytes = System.Convert.FromBase64Ssortingng(encodedData); ssortingng returnValue = System.Text.UnicodeEncoding.Unicode.GetSsortingng(encodedDataAsBytes); return returnValue; } #endregion } 

Et vous pouvez utiliser le type comme ceci:

 static void Main(ssortingng[] 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 Base64Ssortingng Field1; [XmlElement("Beta")] public ssortingng Field2; [XmlElement("Gamma_64")] public Base64Ssortingng Field3; [XmlElement("Delta_64")] public Base64Ssortingng Field4; } 

Vous stockez la chaîne en tant que valeur Base64 et disposez ensuite d’une propriété qui la décode dans la clause get.

Le seul moyen pris en charge de modifier la sortie de la classe XmlSerializer (sans hacks laids, comme avoir des propriétés cachées spéciales, etc.) consiste à implémenter l’interface IXmlSerializable .

Vous pourriez éviter de devoir écrire du code de sérialisation pour toute la classe en définissant une classe Base64Ssortingng qui implémente IXmlSerializable et écrit simplement la chaîne codée. Définissez un opérateur pour le rendre implicitement convertible en chaîne et il devrait fonctionner assez bien comme le ferait une chaîne normale.