MailMessage object and XmlSerializer

0 votes
asked May 4, 2011 by Rebex KB (8,330 points)
edited May 4, 2011

When the MailMessage object is serialized using the XmlSerializer object, the following exception is thrown:

System.InvalidOperationException: Cannot serialize member 'Rebex.Mail.MailMessage.Date' of type 'Rebex.Mime.Headers.MailDateTime', see inner exception for more details.

How do I solve this?

Applies to: Rebex Secure Mail
commented Mar 14, 2015 by nickwelhar (100 points)

1 Answer

+1 vote
answered May 4, 2011 by Rebex KB (8,330 points)
edited May 4, 2011

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).

...