Although the MailMessage
class doesn't support XML-serialization directly, it does support the IFormatter
serialization architecture. This makes it possible to create a wrapper class for the MailMessage
class and use that when persisting or passing the objects around.
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
...
public class MailMessageWrapper : IXmlSerializable
{
public MailMessage Message { get; private set; }
public MailMessageWrapper()
{
Message = new MailMessage();
}
public MailMessageWrapper(MailMessage message)
{
if (message == null)
throw new ArgumentNullException("message");
Message = message;
}
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
{
return null;
}
void IXmlSerializable.ReadXml(XmlReader reader)
{
// create a memory stream for serialized data
var stream = new MemoryStream();
// read serialized data into the stream
reader.ReadStartElement();
var buffer = new byte[1024];
while (true)
{
int count = reader.ReadContentAsBase64(buffer, 0, buffer.Length);
if (count == 0)
break;
stream.Write(buffer, 0, count);
}
stream.Position = 0;
reader.ReadEndElement();
// create an instance of serialization formatter
var formatter = new BinaryFormatter();
// deserialize the inner message
Message = (MailMessage)formatter.Deserialize(stream);
}
void IXmlSerializable.WriteXml(XmlWriter writer)
{
// create a memory stream for serialized data
var stream = new MemoryStream();
// create an instance of serialization formatter
var formatter = new BinaryFormatter();
// serialize the inner message
formatter.Serialize(stream, Message);
// write serialized data into XML
writer.WriteBase64(stream.GetBuffer(), 0, (int)stream.Length);
}
}
The same approach can be used for any object serializable using the IFormatter
architecture (which means any object marked with [Serializable]
attribute).