【问题标题】:How do I serialize a mail message?如何序列化邮件消息?
【发布时间】:2010-11-10 11:01:44
【问题描述】:

我在使用 los foratter 序列化 mial 消息时得到以下信息。

错误:Sys.WebForms.PageRequestManagerServerErrorException:序列化“System.Net.Mail.MailMessage”类型的值“System.Net.Mail.MailMessage”时出错。”

有没有一种简单的方法来序列化这个对象,还是我必须单独序列化每个属性?

【问题讨论】:

  • 你想把它序列化到哪里?
  • 我正在尝试将其放入字节数组中。

标签: .net asp.net email serialization


【解决方案1】:

我知道这是一篇较旧的帖子,但我也遇到了需要序列化 ​​MailAddress 类的问题,因此我创建了一个可序列化的版本。如果您能够使用自定义 MailAddress 类而不是 System.Net.Mail.MailAddress 类,这可能对您有用。

/// <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)))
    {
    }
}

【讨论】:

    【解决方案2】:

    对于那些寻找如何将 MailMessage 序列化为由 Keyvan Nayyeri 编写的 XML 的完整源代码的人,这里是他的 github 的链接:

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

    以下是他的博客存档,现已失效:

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

    以防上面的链接也可能失效,我在这里重新发布他的博客:

    如何序列化邮件消息

    .NET 中有两个 MailMessage 类。第一个在 System.Web.Mail 命名空间中,在 .NET 2.0 及更高版本中已过时,第二个在 System.Net.Mail 中可用。我不关心过时的,所以我只展示如何序列化 System.Net.Mail.MailMessage 类的实例。

    要序列化 ​​MailMessage 对象的属性,您可以创建一个新类并为其创建一个 MailMessage 类型的属性,将您的 MailMessage 嵌入到该类中。在这个新类中,您可以实现 IXmlSerializable 接口来手动序列化其 MailMessage。

    序列化

    序列化方面的工作就像实现 WriteXml 方法一样简单。下面的代码是我为此编写的。

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

    按照相同的方法,您可以序列化其他属性,如附件。下周我将发布新版本的 Gopi,其中包含序列化所有内容的更新代码,因此您可以稍等片刻获得代码。

    反序列化

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

    以上代码使用辅助方法来获取不同部分的 XmlNode。

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

    此代码是不言自明的,不需要任何注释,但请注意,您需要为类名更新 XPath 表达式。当然,我可以使用反射来使这段代码更通用,但有时我是个坏人!

    【讨论】:

      【解决方案3】:

      遗憾的是,System.Net.Mail.MailMessage 类未标记为可序列化。所以,是的,你需要自己做。以下博客文章中描述了一种技术,可以让您了解如何进行操作:How to Serialize a MailMessage ...基本上,您需要单独提取每个属性。引用:

      要序列化 ​​MailMessage 对象的属性,您可以创建一个 新类并为其创建一个 MailMessage 类型的属性 你在课堂上的 MailMessage。在这个新类中,您可以实现 IXmlSerializable 接口手动序列化其MailMessage。这里 我创建了这个类并将其命名为 SerializableMailMessage [...]

      [WriteXml() 和 ReadXml() 方法的代码实现如下;查看源链接]

      【讨论】:

      • 链接重定向到博客主页。
      • @GunnarSteinn 谢谢 - 已修复。
      • 链接仍然断开。
      • @Campinho 该博客已不存在。
      • @ChrisW.Rea 哦,真可惜,有什么新的参考吗?
      猜你喜欢
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多