2009-07-13 12 views
10

Ottengo il seguente quando leghiamo per serializzare un messaggio di fiala utilizzando il foratter los.Come si serializza un messaggio di posta?

Errore: Sys.WebForms.PageRequestManagerServerErrorException: errore serializzazione del valore 'System.Net.Mail.MailMailMessage' di tipo 'System.Net.Mail.MailMessage.'

Esiste un modo semplice per serializzare questo oggetto o sto andando a scovare singolarmente ogni proprietà?

+0

Dove stai cercando di serializzarlo? –

+0

Sto provando a inserirlo in un array di byte. – Middletone

risposta

0

Purtroppo, la classe System.Net.Mail.MailMessage non è contrassegnata come serializzabile. Quindi, sì, dovrai farlo da solo. C'è una tecnica descritta nel seguente post del blog che può darti un'idea di come potresti procedere: How to Serialize a MailMessage ... in pratica, dovrai estrarre ciascuna delle proprietà singolarmente. Citazione:

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]

+0

Il collegamento reindirizza alla home page del blog. –

+0

Il collegamento è interrotto. –

+0

@GunnarSteinn Grazie - risolto. –

2

So che questo è un posto più vecchio, ma ho anche avuto il problema in cui avevo bisogno di serializzare la classe MailAddress così ho creato una versione serializzabile. Se sei in grado di utilizzare una classe personalizzata MailAddress invece della classe System.Net.Mail.MailAddress, questo potrebbe funzionare per te.

/// <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

Per chi cerca il codice sorgente completo su come serializzare MailMessage in XML scritto da Keyvan Nayyeri, ecco il link al suo GitHub:

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

Ed ecco il archivio del suo blog che è ormai defunta:

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

Solo nel caso in cui il link qui sopra potrebbe diventare morto troppo, qui mi ri-pubblicare il suo blog qui:

come serializzare un MailMessage

Ci sono due classi MailMessage in .NET. Il primo è nel namespace System.Web.Mail ed è obsoleto in .NET 2.0 e versioni successive e il secondo è disponibile in System.Net.Mail. Non mi interessa l'obsoleto, quindi mostro solo come serializzare le istanze della classe System.Net.Mail.MailMessage.

Per serializzare le proprietà di un oggetto MailMessage è possibile creare una nuova classe e creare una proprietà di tipo MailMessage per essa che incorpora il tuo MailMessage nella classe. In questa nuova classe è possibile implementare l'interfaccia IXmlSerializable per serializzare manualmente il suo MailMessage.

serializzazione

lato serializzazione del lavoro è semplice come l'attuazione del metodo WriteXml. Il codice seguente è quello che ho scritto per fare questo.

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

Seguendo stesso approccio è possibile serializzare altri immobili come allegati. La prossima settimana rilascerò la nuova versione di Gopi che contiene il codice aggiornato che serializza tutto in modo da poter attendere a breve per mettere le mani sul codice.

deserializzazione

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

Sopra codice utilizza un metodo di supporto per ottenere un XmlNode per le diverse sezioni.

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

Questo codice si spiega da sé e non ha bisogno di alcun commento, ma notare che è necessario aggiornare espressioni XPath per i vostri nomi di classi. Certo, potrei usare la riflessione per rendere questo codice più generale ma a volte sono un cattivo ragazzo !!

Problemi correlati