C# XmlSerializer,base64编码字符串成员

C# XmlSerializer,base64编码字符串成员,c#,xml-serialization,C#,Xml Serialization,考虑一个简单的例子 public class Test { public String myString; } 有什么方法可以让XmlSerializer在序列化myString时对其进行base64编码吗?将该字符串存储为base64值,然后在get子句中使用一个属性对其进行解码。更改XmlSerializer类的输出的唯一受支持的方法(没有像具有特殊隐藏属性等丑陋的黑客)是为了实现IXmlSerializable接口 通过定义一个实现IXmlSerializable的Base64Str

考虑一个简单的例子

public class Test {
  public String myString;
}

有什么方法可以让XmlSerializer在序列化myString时对其进行base64编码吗?

将该字符串存储为base64值,然后在get子句中使用一个属性对其进行解码。

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

通过定义一个实现
IXmlSerializable
Base64String
类,只需写出编码的字符串,就可以省去为整个类编写序列化代码的麻烦。定义一个运算符使其成为字符串,它的工作原理应该与普通字符串类似。

Base64转换二进制数据如果你想用base64编码字符串中的数据,你需要先在字节数组中编码,例如使用
Encoding.UTF.GetBytes(myString)


这就提出了一个问题,为什么您首先要这样做。如果您需要使用base 64,您确定您真的有文本数据开始吗?

您只需将其设置为
字节[]
属性,它就会自动对其进行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>
MQAyADMANAA1ADYANwA4ADkAMQAyADMANAA1ADYANwA4ADkA
(试着解码)


不幸的是,(据我所知)没有办法使MyProperty私有化,并且仍然在
System.Xml.Serialization

中序列化。根据Jon Grant的有用建议,我实现了一个Base64String类型,它封装了所需的Base64编码

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

+1,尽管我会反过来做(简单存储,有一个只为序列化而编码/解码的属性,前提是序列化的使用少于访问字符串)。好的,让字符串文本
“”
“\0”
在默认情况下在往返XML之间的过程中幸存下来会很好。