2010-03-18 3 views
9

J'envoie MailMessages avec un SmtpClient (en cours de livraison) en utilisant un serveur Exchange mais je souhaite que mes courriels envoyés se rendent dans le dossier envoyé de l'adresse e-mail que j'envoie eux de (ne se produit pas).Récupération d'un MailMessage envoyé dans le "Dossier envoyé"

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

Y at-il une configuration que je manque qui assurera tous mes e-mails envoyés par « [email protected] » arrivent dans leur dossier d'envoi?

Répondre

10

Je suppose que votre exigence est principalement orientée vers donner aux utilisateurs la visibilité de ce que les e-mails ont été envoyés. Le dossier des éléments envoyés serait une méthode pour permettre cela. Dans le passé, j'ai résolu ce problème en ajoutant un BCC Address qui envoyait littéralement l'e-mail directement à une liste de distribution, un utilisateur ou une boîte aux lettres partagée permettant aux utilisateurs de vérifier ce qui avait été envoyé.

essayer avec une règle de perspectives d'une sorte pour déplacer l'élément à leurs éléments envoyés dossier marqués comme lus ...

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

Merci pour votre réponse! C'est certainement une considération probable maintenant car c'est littéralement la confirmation dont j'ai besoin ... –

+0

La réponse du service d'échange par LachlanB ci-dessous est la vraie réponse. C'est un peu un hack. – kenjara

0

Vous devez envoyer le message à partir d'Outlook si vous souhaitez que le message envoyé figure dans le dossier "Messages envoyés". Ce dossier est un concept Outlook (et de nombreux autres clients de messagerie), pas un concept SMTP.

Vous pouvez utiliser l'API Outlook Automation pour demander à Outlook de créer un courrier électronique et de l'envoyer.

+0

+1 pour "pas un concept SMTP". C'est en fait le point crucial du problème (bien que l'envoi depuis Outlook ait peu de chances de fonctionner pour l'OP). – OutstandingBill

14

Je l'ai fait, donc pour être complet, voici comment le faire correctement. En utilisant le service Web d'échange géré (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

cela devrait être la meilleure réponse – markthewizard1234

+0

@ markthewizard1234 - Je crois que cette solution, bien qu'élégante, lie l'utilisateur à un fournisseur Exchange. L'OP n'est pas actuellement limité de cette façon car il utilise SmtpClient. – OutstandingBill

+0

@OutstandingBill il a mentionné qu'il utilisait Exchange et il n'y a aucun moyen de le faire avec SmtpClient – Rocklan

1

je cherche une réponse à cette question, mais sans compter sur un serveur Exchange, et utiliser à la place d'un serveur IMAP. Je ne sais pas si cela sort de la portée de la question, mais je l'ai trouvé en cherchant "Obtenir un MailMessage envoyé dans le dossier envoyé" qui était mon problème en premier lieu.

n'avez pas trouvé une réponse directe ne importe où j'ai construit ma propre solution basée sur:

Je mettre en œuvre la méthode d'enregistrement comme une extension de smtpclient si, au lieu de .Send() de nous utiliserons .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; 
    } 
} 

Ainsi, l'exemple de Robert Reid deviendrait

 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"); 
     } 
Questions connexes