对于那些寻找如何将 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 表达式。当然,我可以使用反射来使这段代码更通用,但有时我是个坏人!