簡體   English   中英

XmlSerializer,base64編碼一個String成員

[英]XmlSerializer , base64 encode a String member

考慮一個簡單的案例

public class Test {
  public String myString;
}

有什么辦法可以告訴XmlSerializer在序列化時對base64編碼myString嗎?

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

您可以簡單地將其設置為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");

輸出:

<MyProperty>MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA</MyProperty>

(嘗試解碼功能, 在這里

不幸的是,我無法(我知道)將MyProperty設為私有,並且仍然在System.Xml.Serialization進行序列化。

將字符串存儲為Base64值,然后具有在get子句中對其進行解碼的屬性。

XmlSerializer類更改輸出的唯一受支持的方法(沒有丑陋的黑客,如具有特殊的隱藏屬性等)是實現IXmlSerializable接口。

您可以通過定義實現IXmlSerializableBase64String類並僅寫出編碼的字符串來節省自己必須為整個類編寫序列化代碼。 定義一個運算符,使其可以隱式地轉換為字符串,它應該像普通字符串一樣工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM