Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I serialize a mail message?

I get the following when tying to serialize a mial message using the los foratter.

Error: Sys.WebForms.PageRequestManagerServerErrorException: Error serializing value 'System.Net.Mail.MailMessage' of type 'System.Net.Mail.MailMessage.'

Is there an EASY way to serialize this object or am I going have to searialize each o fhte properties individually?

like image 669
Middletone Avatar asked Jul 13 '09 21:07

Middletone


People also ask

Is it possible to serialize a mailmessage class?

Sadly, the System.Net.Mail.MailMessage class is not marked as serializable. So, yes, you'll need to do it yourself. There's a technique described in the following blog post that can give you an idea of how you might proceed: How to Serialize a MailMessage ... basically, you will need to pull out each of the properties individually.

How do I serialize a thread?

My simple version of serialization was my little helper. Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Why doesn't JavaMail support Java serialization?

A: The JavaMail API was designed to layer on top of existing email systems, using existing message formats. The ability to use Java serialization was neither essential nor useful for such implementations, and thus was not considered a goal of the JavaMail API.

How do I send an email with S/MIME?

In an email message, choose Options, select Encrypt and pick Encrypt with S/MIME option from the drop down, You'll see an Encrypt with S/MIME if you have an S/MIME certificate installed on your computer. In an email message, choose Options, select Permissions. Finish composing your email and then choose Send.


2 Answers

I know this is an older post, but I also had the issue where I needed to serialize the MailAddress class so I created a serializable version. If you're in a position to use a custom MailAddress class instead of the System.Net.Mail.MailAddress class, this may work for you.

/// <summary>
/// Serializable implementation of <see cref="System.Net.Mail.MailAddress"/>.
/// </summary>
[Serializable]
public class MailAddress : System.Net.Mail.MailAddress, ISerializable
{
    // Keep reference to the display name encoding so we can serialize/deserialize the value
    private readonly Encoding _displayNameEncoding;

    public MailAddress(string address)
        : this(address, null, null)
    {
    }

    public MailAddress(string address, string displayName)
        : this(address, displayName, null)
    {
    }

    public MailAddress(string address, string displayName, Encoding displayNameEncoding)
        : base(address, displayName, displayNameEncoding)
    {
        // Keep reference to the supplied displayNameEncoding so we can serialize/deserialize this value
        _displayNameEncoding = displayNameEncoding ?? Encoding.GetEncoding("utf-8");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Address", base.Address);
        info.AddValue("DisplayName", base.DisplayName);
        info.AddValue("DisplayNameEncoding", _displayNameEncoding);
    }

    protected MailAddress(SerializationInfo info, StreamingContext context)
        : this(info.GetString("Address"), info.GetString("DisplayName"), (Encoding)info.GetValue("DisplayNameEncoding", typeof (Encoding)))
    {
    }
}
like image 166
Steve Dignan Avatar answered Nov 13 '22 04:11

Steve Dignan


For those looking for the full source code on how to serialize MailMessage into XML written by Keyvan Nayyeri, here is the link to his github:

https://github.com/keyvan/Gopi/blob/master/Gopi/Gopi/SerializableMailMessage.cs

And here is the archive of his blog that is now defunct:

http://web.archive.org/web/20131124074822/http://keyvan.io/how-to-serialize-a-mailmessage

Just in case the link above might become dead too, here I re-post his blog here:

How to Serialize a MailMessage

There are two MailMessage classes in .NET. First one is in System.Web.Mail namespace and is obsolete in .NET 2.0 and later and the second one is available in System.Net.Mail. I don't care about the obsolete one so I just show how you can serialize instances of System.Net.Mail.MailMessage class.

To serialize the properties of a MailMessage object you can create a new class and create a property of MailMessage type for it that embeds your MailMessage in the class. In this new class you can implement IXmlSerializable interface to manually serialize its MailMessage.

Serialization

Serialization side of the work is as simple as implementing the WriteXml method. The below code is what I've written to do this.

public void WriteXml(XmlWriter writer)
{
    if (this != null)
    {
        writer.WriteStartElement("MailMessage");
        writer.WriteAttributeString("Priority", Convert.ToInt16(this.Priority).ToString());
        writer.WriteAttributeString("IsBodyHtml", this.IsBodyHtml.ToString());

        // From
        writer.WriteStartElement("From");
        if (!string.IsNullOrEmpty(this.From.DisplayName))
            writer.WriteAttributeString("DisplayName", this.From.DisplayName);
        writer.WriteRaw(this.From.Address);
        writer.WriteEndElement();

        // To
        writer.WriteStartElement("To");
        writer.WriteStartElement("Addresses");
        foreach (MailAddress address in this.To)
        {
            writer.WriteStartElement("Address");
            if (!string.IsNullOrEmpty(address.DisplayName))
                writer.WriteAttributeString("DisplayName", address.DisplayName);
            writer.WriteRaw(address.Address);
            writer.WriteEndElement();
        }
        writer.WriteEndElement();
        writer.WriteEndElement();

        // CC
        if (this.CC.Count > 0)
        {
            writer.WriteStartElement("CC");
            writer.WriteStartElement("Addresses");
            foreach (MailAddress address in this.CC)
            {
                writer.WriteStartElement("Address");
                if (!string.IsNullOrEmpty(address.DisplayName))
                    writer.WriteAttributeString("DisplayName", address.DisplayName);
                writer.WriteRaw(address.Address);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

        // Bcc
        if (this.Bcc.Count > 0)
        {
            writer.WriteStartElement("Bcc");
            writer.WriteStartElement("Addresses");
            foreach (MailAddress address in this.Bcc)
            {
                writer.WriteStartElement("Address");
                if (!string.IsNullOrEmpty(address.DisplayName))
                    writer.WriteAttributeString("DisplayName", address.DisplayName);
                writer.WriteRaw(address.Address);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

        // Subject
        writer.WriteStartElement("Subject");
        writer.WriteRaw(this.Subject);
        writer.WriteEndElement();

        // Body
        writer.WriteStartElement("Body");
        writer.WriteCData(Body);
        writer.WriteEndElement();

        writer.WriteEndElement();
    }
}

Following same approach you can serialize other properties like Attachments. Next week I'll release the new version of Gopi that contains the updated code that serializes everything so you can wait shortly to get your hands on the code.

Deserialization

public void ReadXml(XmlReader reader)
{
    XmlDocument xml = new XmlDocument();
    xml.Load(reader);

    // Properties
    XmlNode rootNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage");
    this.IsBodyHtml = Convert.ToBoolean(rootNode.Attributes["IsBodyHtml"].Value);
    this.Priority = (MailPriority)Convert.ToInt16(rootNode.Attributes["Priority"].Value);

    // From
    XmlNode fromNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/From");
    string fromDisplayName = string.Empty;
    if (fromNode.Attributes["DisplayName"] != null)
        fromDisplayName = fromNode.Attributes["DisplayName"].Value;
    MailAddress fromAddress = new MailAddress(fromNode.InnerText, fromDisplayName);
    this.From = fromAddress;

    // To
    XmlNode toNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/To/Addresses");
    foreach (XmlNode node in toNode.ChildNodes)
    {
        string toDisplayName = string.Empty;
        if (node.Attributes["DisplayName"] != null)
            toDisplayName = node.Attributes["DisplayName"].Value;
        MailAddress toAddress = new MailAddress(node.InnerText, toDisplayName);
        this.To.Add(toAddress);
    }

    // CC
    XmlNode ccNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/CC/Addresses");
    foreach (XmlNode node in ccNode.ChildNodes)
    {
        string ccDisplayName = string.Empty;
        if (node.Attributes["DisplayName"] != null)
            ccDisplayName = node.Attributes["DisplayName"].Value;
        MailAddress ccAddress = new MailAddress(node.InnerText, ccDisplayName);
        this.CC.Add(ccAddress);
    }

    // Bcc
    XmlNode bccNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/Bcc/Addresses");
    foreach (XmlNode node in bccNode.ChildNodes)
    {
        string bccDisplayName = string.Empty;
        if (node.Attributes["DisplayName"] != null)
            bccDisplayName = node.Attributes["DisplayName"].Value;
        MailAddress bccAddress = new MailAddress(node.InnerText, bccDisplayName);
        this.Bcc.Add(bccAddress);
    }

    // Subject
    XmlNode subjectNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/Subject");
    this.Subject = subjectNode.InnerText;

    // Body
    XmlNode bodyNode = GetConfigSection(xml, "SerializableMailMessage/MailMessage/Body");
    this.Body = bodyNode.InnerText;
}

Above code uses a helper method to get an XmlNode for different sections.

public XmlNode GetConfigSection(XmlDocument xml, string nodePath)
{
    return xml.SelectSingleNode(nodePath);
}

This code is self-explanatory and doesn't need any comment but note that you need to update XPath expressions for your class names. Of course, I could use reflection to make this code more general but sometimes I'm a bad guy!!

like image 28
Rosdi Kasim Avatar answered Nov 13 '22 05:11

Rosdi Kasim