2010-03-18 117 views
9

我使用Exchange Server发送带有SmtpClient的MailMessages(正在成功发送),但希望我发送的电子邮件能够发送到我发送的电子邮件地址的发送文件夹他们从(不发生)。将已发送的MailMessage发送到“发送的文件夹”

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

是有我丢失,这将确保所有我发送的电子邮件从“[email protected]”这样的配置,他们发送文件夹到吗?

回答

10

我猜你的要求主要是围绕让用户知道发送了哪些电子邮件。发送的项目文件夹将是一种允许发生这种情况的方法。在过去,我通过添加一个BCC Address来解决这个问题,它可以直接将电子邮件发送到分发列表,用户或共享邮箱,以便用户查看发送的内容。

与某种Outlook规则尝试使用此方法将项目移至其发送邮件文件夹标记为已读...

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

感谢您的回复!这绝对是一个可能的考虑因素,因为它实际上就是我需要的确认... – 2010-03-18 16:51:22

+0

LachlanB下面的Exchange服务答案是真正的答案。这有点破解。 – kenjara 2016-04-07 14:05:03

0

如果要在“已发送邮件”文件夹中发送邮件,则需要从Outlook发送邮件。这个文件夹是一个Outlook(和许多其他邮件客户端)概念,而不是SMTP概念。

您可以使用Outlook自动化API来要求Outlook创建电子邮件并发送它。

+0

+1 “不是一个概念SMTP”。这实际上是问题的症结所在(虽然从Outlook发送不太可能用于OP)。 – OutstandingBill 2017-05-22 08:01:46

14

我已经做到了这一点,所以为了完整性这里是如何正确地做到这一点。使用托管交换网络服务(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

这应该是最佳答案 – markthewizard1234 2017-02-06 12:34:43

+0

@ markthewizard1234 - 我相信这个解决方案虽然很优雅,但却将用户与Exchange提供商联系起来。由于他们正在使用SmtpClient,因此OP目前并未受到这种限制。 – OutstandingBill 2017-05-22 07:57:25

+0

@OutstandingBill他提到他正在使用Exchange,并且没有办法用SmtpClient来做到这一点 – Rocklan 2017-05-23 03:57:43

1

我一直在寻找的答案,这个问题,但不依靠一个Exchange服务器上,而是使用IMAP服务器。我不知道这是否超出了问题的范围,但是我发现它搜索“将已发送的邮件消息发送到已发送的文件夹”,这首先是我的问题。

还没有找到一个直接的回答我的任何地方建立了自己的解决方案基于:

我执行的保存方法的一个扩展smtpClient如此,而不是.Send(),我们将使用.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; 
    } 
} 

所以罗伯特·里德的例子将成为

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