2009-09-10 13 views

Respuesta

3

Simplemente puede configurarlo para que sea una propiedad byte[] y va a Base64 codificar automáticamente:

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

Salida:

<MyProperty>MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA</MyProperty> 

(Trate decodificación que here)

Lamentablemente no de ninguna manera (que yo sepa) para hacer que MyProperty sea privado y aún se serialice en System.Xml.Serialization.

2

Almacena la cadena como un valor de Base64 y luego tiene una propiedad que lo decodifica en la cláusula get.

+1

+1, aunque lo haría al revés (la tienda normal, tienen una propiedad que codifica/decodifica sólo para la serialización , siempre que la serialización sea menos utilizada que solo acceder a la cadena). – OregonGhost

0

La única forma admitida de cambiar la salida de la clase XmlSerializer (sin hacks feos como tener propiedades ocultas especiales, etc.) es implementar la interfaz IXmlSerializable.

Puede ahorrarse tener que escribir el código de serialización para toda la clase definiendo una clase Base64String que implementa IXmlSerializable y acaba de escribir la cadena codificada. Defina un operador para convertirlo en implicitly castable en una cadena y debería funcionar más o menos como lo hace una cadena normal.

4

Base64 convierte datos binarios en una cadena. Si desea base64 codificar los datos en una cadena, primero deberá codificarla en matriz de bytes, p. usando Encoding.UTF.GetBytes(myString).

Esto plantea la pregunta de por qué exactamente querrías hacer esto en primer lugar. Si necesita usar la base 64, ¿está seguro de que realmente tiene datos de texto para comenzar?

+1

Bueno, tener las cadenas literales '" "' y '" \ 0 "' sobrevivir a un viaje de ida y vuelta a XML por defecto sería bueno. – binki

4

siguiendo la sugerencia útil de Jon Grant He implementado un tipo Base64String que encapsula la Codificación Base64 requerida.

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 
} 

Y se puede utilizar el tipo de la siguiente manera:

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; 
} 
Cuestiones relacionadas