使用los foratter绑定mial消息时,我得到以下内容。
错误:Sys.WebForms.PageRequestManagerServerErrorException:序列化'System.Net.Mail.MailMessage'类型的值'System.Net.Mail.MailMessage'时出错。
是否有一种简单的方法来序列化这个对象,或者我是否需要单独对每个ohhte属性进行分类?
答案 0 :(得分:4)
对于那些寻找关于如何将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
如果上面的链接也可能已经死了,我在这里重新发布他的博客:
如何序列化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表达式。当然,我可以使用反射来使这段代码更加通用,但有时候我是个坏人!!
答案 1 :(得分:3)
我知道这是一篇较旧的帖子,但我也遇到了需要序列化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 :(得分:1)
可悲的是,System.Net.Mail.MailMessage类未标记为可序列化。所以,是的,你需要自己做。以下博客文章中描述了一种技术,可以让您了解如何继续:How to Serialize a MailMessage ...基本上,您需要单独提取每个属性。引用:
要序列化MailMessage对象的属性,可以创建一个 新类并为其嵌入的MailMessage类型创建一个属性 你在课堂上的MailMessage。在这个新课程中你可以实现 IXmlSerializable接口,用于手动序列化其MailMessage。这里 我创建了这个类,并将其命名为SerializableMailMessage [...]
[WriteXml()和ReadXml()方法的代码实现如下;见源链接]