如何序列化郵件消息?
使用 los foratter 序列化 mial 消息時,我得到以下資訊。
錯誤:Sys.WebForms.PageRequestManagerServerErrorException:序列化“System.Net.Mail.MailMessage”類型的值“System.Net.Mail.MailMessage”時出錯。
有沒有一種簡單的方法來序列化這個對象,還是我必須單獨序列化每個 fhte 屬性?
我知道這是一篇較舊的文章,但我也遇到了需要序列化 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))) { } }
對於那些尋找如何將 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 表達式。當然,我可以使用反射來使這段程式碼更通用,但有時我是個壞人!