My first reaction is: don't do this.
By creating your own encoding for an array of strings, your XML is not going to be (easily) consumable by other programs. By Base64 encoding your strings, your XML is not going to be human-readable.
These are two major benefits of XML, and if you're willing to sacrifice them, maybe XML is not the right format. If the serialized data is only going to be consumed by the same program, binary serialization would be a better option.
That said, if you want to serialize a list of strings to XML, this is what I would recommend:
public class Email
{
private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(Email));
[XmlArrayItem("Attachment")]
public List<string> Attachments { get; set; }
public XDocument ToXDocument()
{
var document = new XDocument();
using (var writer = document.CreateWriter())
{
new XmlSerializer(GetType())Serializer.Serialize(writer, this);
}
return document;
}
}
And some sample client code:
var email = new Email
{
Attachments = new List<string> { "<hello></hello>", "asdf" }
};
var xml = email.ToXDocument().ToString();
Console.WriteLine(xml);
This will output
<Email xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Attachments>
<Attachment><hello></hello></Attachment>
<Attachment>asdf</Attachment>
</Attachments>
</Email>
Now, this chokes if the strings contain a null-byte, which you mentioned was a possibility. It's hard to say what to do about this without knowing more about your problem domain. Hopefully, stripping null-bytes is an option for you.
Serializing a byte[] as a Base64-encoded string can be done using a surrogate property:
[XmlIgnore]
public byte[] Bytes { get; set; }
public string BytesBase64
{
get { return Convert.ToBase64String(this.Bytes); }
set { this.Bytes = Convert.FromBase64String(value); }
}