2009-09-10 12 views

Antwort

3

können Sie einfach festlegen es eine byte[] Eigenschaft sein, und es wird Base64 kodieren sie automatisch:

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"); 

Ausgang:

<MyProperty>MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA</MyProperty> 

(Versuchen Decodierung, dass here)

Leider gibt ist keine Möglichkeit (die ich kenne), MyProperty privat zu machen und trotzdem in System.Xml.Serialization serialisiert zu werden.

2

Sie speichern die Zeichenfolge als einen Base64-Wert und verfügen dann über eine Eigenschaft, die es in der Get-Klausel dekodiert.

+1

+1, obwohl ich es andersherum machen würde (Speicher Ebene, haben eine Eigenschaft, die/kodiert sie dekodiert nur für die Serialisierung , vorausgesetzt, die Serialisierung wird weniger verwendet als nur der Zugriff auf die Zeichenfolge. – OregonGhost

0

Die einzige unterstützte Möglichkeit, die Ausgabe aus der Klasse XmlSerializer (ohne hässliche Hacks wie spezielle versteckte Eigenschaften usw.) zu ändern, ist die Implementierung der IXmlSerializable Schnittstelle.

Sie könnten sich das Schreiben von Serialisierungscode für die gesamte Klasse ersparen, indem Sie eine Base64String Klasse definieren, die IXmlSerializable implementiert und nur die codierte Zeichenfolge ausgibt. Definieren Sie einen Operator, um implicitly castable zu einem String zu machen, und es sollte so funktionieren wie ein normaler String.

4

Base64 konvertiert binäre Daten in eine Zeichenfolge. Wenn Sie die Daten in einer Zeichenfolge mit Base64 codieren möchten, müssen Sie sie zuerst im Byte-Array codieren, z. mit Encoding.UTF.GetBytes(myString).

Dies wirft die Frage auf, warum genau Sie das überhaupt erst machen möchten. Wenn Sie Base 64 verwenden müssen, sind Sie sicher, dass Sie wirklich Textdaten haben?

+1

Nun, die Zeichenfolgenliterale '' '' und '" \ 0 "' würden einen Umlauf nach/von XML standardmäßig überstehen, wäre nett. – binki

4

Nach Jon Grant nützlichen Vorschlag Ich habe einen Base64String-Typ implementiert, die die erforderliche Base64-Codierung einkapseln.

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 
} 

Und Sie können die Art wie diese verwenden:

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; 
} 
Verwandte Themen