2010-03-18 7 views
9

Sto inviando messaggi di posta con uno SmtpClient (consegnato correttamente) utilizzando un server di Exchange ma vorrei che i miei messaggi di posta elettronica inviati andassero alla cartella inviata dell'indirizzo di posta elettronica che sto inviando da (non sta accadendo).Invio di un messaggio di posta nella "cartella inviata"

using (var mailMessage = new MailMessage("[email protected]", "[email protected]", "subject", "body")) 
{ 
    var smtpClient = new SmtpClient("SmtpHost") 
    { 
     EnableSsl = false, 
     DeliveryMethod = SmtpDeliveryMethod.Network 
    }; 

    // Apply credentials 
    smtpClient.Credentials = new NetworkCredential("smtpUsername", "smtpPassword"); 

    // Send 
    smtpClient.Send(mailMessage); 
} 

C'è una configurazione che mi manca che garantirà tutte le mie e-mail inviate da "[email protected]" arrivano nella loro cartella posta inviata?

risposta

10

Immagino che la vostra esigenza sia principalmente orientata a dare agli utenti visibilità su quali e-mail sono state inviate. La cartella degli articoli inviati sarebbe un metodo per consentire che ciò si verifichi. In passato, ho risolto questo problema aggiungendo uno BCC Address che avrebbe letteralmente inviato l'e-mail direttamente a una lista di distribuzione, a un utente o a una casella di posta condivisa che consentiva agli utenti di rivedere ciò che era stato inviato.

Prova questa con una regola di Outlook di qualche tipo per spostare la voce ai loro cartella Posta inviata contrassegnato come leggere ...

using (var mailMessage = new MailMessage(
     "[email protected]", 
     "[email protected]", 
     "", 
     "[email protected]", 
     "subject", 
     "body")) 
{ 
    var smtpClient = new SmtpClient("SmtpHost") 
    { 
     EnableSsl = false, 
     DeliveryMethod = SmtpDeliveryMethod.Network 
    }; 

    // Apply credentials 
    smtpClient.Credentials = new NetworkCredential("smtpUsername", "smtpPassword"); 

    // Send 
    smtpClient.Send(mailMessage); 
} 
+2

Grazie per la tua risposta! Questa è sicuramente una considerazione probabile ora che è letteralmente solo la conferma che mi serve ... –

+0

Il servizio di risposta di risposta di LachlanB sotto è la vera risposta. Questo è un po 'un trucco. – kenjara

0

È necessario inviare il messaggio da Outlook se si desidera che il messaggio sia inviato nella cartella "Messaggi inviati". Questa cartella è un concetto di Outlook (e molti altri client di posta), non un concetto SMTP.

È possibile utilizzare l'API di automazione di Outlook per chiedere a Outlook di creare un'e-mail e inviarla.

+0

+1 per "non è un concetto di SMTP". Questo è in realtà il punto cruciale del problema (anche se l'invio da Outlook è improbabile che funzioni per l'OP). – OutstandingBill

14

ho fatto questo, quindi per completezza ecco come farlo correttamente. Utilizzando il servizio gestito di scambio web (http://msdn.microsoft.com/en-us/library/dd633709%28EXCHG.80%29.aspx):

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1); 

// In case you have a dodgy SSL certificate: 
System.Net.ServicePointManager.ServerCertificateValidationCallback = 
      delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 
      { 
       return true; 
      }; 

service.Credentials = new WebCredentials("username", "password", "MYDOMAIN"); 
service.Url = new Uri("https://exchangebox/EWS/Exchange.asmx"); 

EmailMessage em = new EmailMessage(service); 
em.Subject = "example email"; 
em.Body = new MessageBody("hello world"); 
em.Sender = new Microsoft.Exchange.WebServices.Data.EmailAddress("[email protected]"); 
em.ToRecipients.Add(new Microsoft.Exchange.WebServices.Data.EmailAddress("[email protected]")); 

// Send the email and put it into the SentItems: 
em.SendAndSaveCopy(WellKnownFolderName.SentItems); 
+0

questa dovrebbe essere la risposta migliore – markthewizard1234

+0

@ markthewizard1234 - Credo che questa soluzione, pur elegante, leghi l'utente a un provider di Exchange. L'OP non è attualmente limitato in questo modo poiché utilizza SmtpClient. – OutstandingBill

+0

@OutstandingBill ha detto che stava usando Exchange e non c'è modo di farlo con SmtpClient – Rocklan

1

Sono stato alla ricerca di una risposta a questa domanda, ma senza fare affidamento su un server Exchange, e di utilizzare invece un server IMAP. Non so se questo rientra nello scopo della domanda, ma ho trovato la ricerca di "Ottenere un messaggio di posta inviato nella cartella di posta", che era il mio problema in primo luogo.

non hanno trovato una risposta diretta da nessuna parte ho costruito la mia propria soluzione basata su:

sto attuazione del metodo di salvataggio come estensione di SmtpClient così, invece di di .Send() useremo .SendAndSaveMessageToIMAP().

public static class SmtpClientExtensions 
{ 
    static System.IO.StreamWriter sw = null; 
    static System.Net.Sockets.TcpClient tcpc = null; 
    static System.Net.Security.SslStream ssl = null; 
    static string path; 
    static int bytes = -1; 
    static byte[] buffer; 
    static System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
    static byte[] dummy; 

    /// <summary> 
    /// Communication with server 
    /// </summary> 
    /// <param name="command">The command beeing sent</param> 
    private static void SendCommandAndReceiveResponse(string command) 
    { 
     try 
     { 
      if (command != "") 
      { 
       if (tcpc.Connected) 
       { 
        dummy = System.Text.Encoding.ASCII.GetBytes(command); 
        ssl.Write(dummy, 0, dummy.Length); 
       } 
       else 
       { 
        throw new System.ApplicationException("TCP CONNECTION DISCONNECTED"); 
       } 
      } 
      ssl.Flush(); 

      buffer = new byte[2048]; 
      bytes = ssl.Read(buffer, 0, 2048); 
      sb.Append(System.Text.Encoding.ASCII.GetString(buffer)); 

      sw.WriteLine(sb.ToString()); 
      sb = new System.Text.StringBuilder(); 
     } 
     catch (System.Exception ex) 
     { 
      throw new System.ApplicationException(ex.Message); 
     } 
    } 

    /// <summary> 
    /// Saving a mail message before beeing sent by the SMTP client 
    /// </summary> 
    /// <param name="self">The caller</param> 
    /// <param name="imapServer">The address of the IMAP server</param> 
    /// <param name="imapPort">The port of the IMAP server</param> 
    /// <param name="userName">The username to log on to the IMAP server</param> 
    /// <param name="password">The password to log on to the IMAP server</param> 
    /// <param name="sentFolderName">The name of the folder where the message will be saved</param> 
    /// <param name="mailMessage">The message being saved</param> 
    public static void SendAndSaveMessageToIMAP(this System.Net.Mail.SmtpClient self, System.Net.Mail.MailMessage mailMessage, string imapServer, int imapPort, string userName, string password, string sentFolderName) 
    { 
     try 
     { 
      path = System.Environment.CurrentDirectory + "\\emailresponse.txt"; 

      if (System.IO.File.Exists(path)) 
       System.IO.File.Delete(path); 

      sw = new System.IO.StreamWriter(System.IO.File.Create(path)); 

      tcpc = new System.Net.Sockets.TcpClient(imapServer, imapPort); 

      ssl = new System.Net.Security.SslStream(tcpc.GetStream()); 
      ssl.AuthenticateAsClient(imapServer); 
      SendCommandAndReceiveResponse(""); 

      SendCommandAndReceiveResponse(string.Format("$ LOGIN {1} {2} {0}", System.Environment.NewLine, userName, password)); 

      using (var m = mailMessage.RawMessage()) 
      { 
       m.Position = 0; 
       var sr = new System.IO.StreamReader(m); 
       var myStr = sr.ReadToEnd(); 
       SendCommandAndReceiveResponse(string.Format("$ APPEND {1} (\\Seen) {{{2}}}{0}", System.Environment.NewLine, sentFolderName, myStr.Length)); 
       SendCommandAndReceiveResponse(string.Format("{1}{0}", System.Environment.NewLine, myStr)); 
      } 
      SendCommandAndReceiveResponse(string.Format("$ LOGOUT{0}", System.Environment.NewLine)); 
     } 
     catch (System.Exception ex) 
     { 
      System.Diagnostics.Debug.WriteLine("error: " + ex.Message); 
     } 
     finally 
     { 
      if (sw != null) 
      { 
       sw.Close(); 
       sw.Dispose(); 
      } 
      if (ssl != null) 
      { 
       ssl.Close(); 
       ssl.Dispose(); 
      } 
      if (tcpc != null) 
      { 
       tcpc.Close(); 
      } 
     } 

     self.Send(mailMessage); 
    } 
} 
public static class MailMessageExtensions 
{ 
    private static readonly System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic; 
    private static readonly System.Type MailWriter = typeof(System.Net.Mail.SmtpClient).Assembly.GetType("System.Net.Mail.MailWriter"); 
    private static readonly System.Reflection.ConstructorInfo MailWriterConstructor = MailWriter.GetConstructor(Flags, null, new[] { typeof(System.IO.Stream) }, null); 
    private static readonly System.Reflection.MethodInfo CloseMethod = MailWriter.GetMethod("Close", Flags); 
    private static readonly System.Reflection.MethodInfo SendMethod = typeof(System.Net.Mail.MailMessage).GetMethod("Send", Flags); 

    /// <summary> 
    /// A little hack to determine the number of parameters that we 
    /// need to pass to the SaveMethod. 
    /// </summary> 
    private static readonly bool IsRunningInDotNetFourPointFive = SendMethod.GetParameters().Length == 3; 

    /// <summary> 
    /// The raw contents of this MailMessage as a MemoryStream. 
    /// </summary> 
    /// <param name="self">The caller.</param> 
    /// <returns>A MemoryStream with the raw contents of this MailMessage.</returns> 
    public static System.IO.MemoryStream RawMessage(this System.Net.Mail.MailMessage self) 
    { 
     var result = new System.IO.MemoryStream(); 
     var mailWriter = MailWriterConstructor.Invoke(new object[] { result }); 
     SendMethod.Invoke(self, Flags, null, IsRunningInDotNetFourPointFive ? new[] { mailWriter, true, true } : new[] { mailWriter, true }, null); 
     result = new System.IO.MemoryStream(result.ToArray()); 
     CloseMethod.Invoke(mailWriter, Flags, null, new object[] { }, null); 
     return result; 
    } 
} 

Quindi l'esempio di Robert Reid sarebbe diventato

 using (var mailMessage = new MailMessage("[email protected]", "[email protected]", "subject", "body")) 
     { 
      //Add an attachment just for the sake of it 
      Attachment doc = new Attachment(@"filePath"); 
      doc.ContentId = "doc"; 
      mailMessage.Attachments.Add(doc); 

      var smtpClient = new SmtpClient("SmtpHost") 
      { 
       EnableSsl = false, 
       DeliveryMethod = SmtpDeliveryMethod.Network 
      }; 

      // Apply credentials 
      smtpClient.Credentials = new NetworkCredential("smtpUsername", "smtpPassword"); 

      // Send 
      smtpClient.SendAndSaveMessageToIMAP(mailMessage, "imap.mail.com", 993, "imapUsername", "imapPassword", "SENT"); 
     }