2009-07-13 80 views
10

當使用los foratter綁定一個mial消息時,我得到以下內容。如何序列化郵件消息?

錯誤:Sys.WebForms.PageRequestManagerServerErrorException:錯誤序列化類型爲'System.Net.Mail.MailMessage'的值'System.Net.Mail.MailMessage'。

是否有一個簡單的方法來序列化這個對象,或者我將不得不單獨搜索每個屬性?

+0

你在哪裏試圖序列化它? – 2009-07-13 23:37:31

+0

我試圖把它放到一個字節數組中。 – Middletone 2009-07-14 01:07:22

回答

0

不幸的是,System.Net.Mail.MailMessage類未標記爲可序列化。所以,是的,你需要自己做。在以下博客文章中介紹了一種技術,可以讓您瞭解如何繼續:How to Serialize a MailMessage ...基本上,您需要單獨提取每個屬性。報價:

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. Here I create this class and call it SerializableMailMessage [...]

[code implementation of WriteXml() and ReadXml() methods follow; see source link]

2

我知道這是一個較舊的職位,但我也有地方,我需要序列化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

萬一上面的鏈接可能變得太死,在這裏,我在這裏重新發布他的博客:

如何序列MAILMESSAGE一個

有在.NET 2類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表達式爲你的類名。當然,我可以使用反射來使這個代碼更一般,但有時我是一個壞人!