2011-06-05 360 views
35

我們正在測試新的Office 365測試版,並且我在Exchange Online服務上有一個郵件帳戶。現在我試圖連接一個可以從我的測試帳戶發送smtp電子郵件的LOB應用程序。通過Exchange Online(Office 365)使用System.Net.Mail發送SMTP電子郵件

但是,Exchange 365平臺需要在端口587上進行TLS加密,並且存在不允許隱式SSL加密的System.Net.Mail「功能」。

有沒有人設法讓C#通過這個平臺發送郵件?

我有以下基本代碼應發送郵件 - 任何意見將不勝感激。

SmtpClient server = new SmtpClient("ServerAddress"); 
server.Port = 587; 
server.EnableSsl = true; 
server.Credentials = new System.Net.NetworkCredential("[email protected]", "password"); 
server.Timeout = 5000; 
server.UseDefaultCredentials = false; 

MailMessage mail = new MailMessage(); 
mail.From = new MailAddress("[email protected]"); 
mail.To.Add("[email protected]"); 
mail.Subject = "test out message sending"; 
mail.Body = "this is my message body"; 
mail.IsBodyHtml = true; 

server.Send(mail); 
+2

它給出了什麼錯誤? – BugFinder 2011-06-05 17:51:52

+0

是的你得到一個超時 - 這顯然是默認的失敗 – 2011-06-06 10:10:34

+0

所以即時通訊開始懷疑這是甚至可能使用C#和System.Net.Mail命名空間通過SSL設置的限制。看起來Exchange有它在Office 365上公開的webservices,很多文章都討論瞭如何利用它來處理郵箱等。但是我真的不想將整個郵箱公開給我的LOB應用程序。 SMTP中的'S'代表'簡單' - 我不相信微軟安裝的微軟郵件服務器不能與微軟的編程語言一起工作。請有人告訴我在這裏錯過了一些東西! – 2011-06-22 11:07:31

回答

10

快速回答:FROM地址必須與您發送的帳戶完全匹配,否則您將收到錯誤5.7.1客戶端無權發送此發件人。

我的猜測是,它可以防止用您的Office 365帳戶欺騙電子郵件,否則您可能會以[email protected]的身份發送郵件。

另一件事,試圖在身份驗證,填寫帶有域的第三場,像

Dim smtpAuth = New System.Net.NetworkCredential(
    "TheDude", "hunter2password", "MicrosoftOffice365Domain.com") 

如果不工作,仔細檢查您可以登錄到帳戶:https://portal.microsoftonline.com

還有一點要注意的是,您的防病毒解決方案可能會阻止程序化訪問端口25和587作爲反垃圾郵件解決方案。諾頓和McAfee可能會默默阻止對這些端口的訪問。只有啓用郵件和套接字調試才能讓你注意到它(見下文)。

最後要注意的一點,發送方法是異步。如果您在致電發送後立即致電

Dispose
,則在發送郵件之前,您很可能會關閉連接。讓你的smtpClient實例監聽OnSendCompleted事件,並從那裏調用dispose。您必須改用SendAsync方法,Send方法不會引發此事件。


詳細答案:與Visual Studio(VB.NET或C#並不重要),我做一個簡單的形式與創建郵件消息,類似於上面的按鈕。然後我將它添加到application.exe.config中(在我的項目的bin/debug目錄中)。這使輸出選項卡具有詳細的調試信息。

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics> 
     <sources> 
      <source name="System.Net"> 
       <listeners> 
        <add name="System.Net" /> 
       </listeners> 
      </source> 
      <source name="System.Net.Sockets"> 
       <listeners> 
        <add name="System.Net" /> 
       </listeners> 
      </source> 
     </sources> 
     <switches> 
      <add name="System.Net" value="Verbose" /> 
      <add name="System.Net.Sockets" value="Verbose" /> 
     </switches> 
     <sharedListeners> 
      <add name="System.Net" 
       type="System.Diagnostics.TextWriterTraceListener" 
       initializeData="System.Net.log" 
      /> 
     </sharedListeners> 
     <trace autoflush="true" /> 
    </system.diagnostics> 
</configuration> 
+1

我假設'hunter2password'不是你的密碼? – rhughes 2014-05-20 06:31:54

+2

呃,是的,那就是對irc meme的那個舊的引用。我的密碼是***************。 Src:http://ars.userfriendly.org/cartoons/?id=19990814 – 2014-05-20 17:40:11

+1

如果您將MailMessage.Sender屬性添加到O365授權的「代理髮送」電子郵件中,MailMessage.From不一定是主要帳戶電子郵件地址。有關詳細信息,請參閱此主題中的我的文章:http://stackoverflow.com/a/33613150/2464869 – ShaneLS 2015-11-09 17:16:07

1

最後,作品!

smtpClient.UseDefaultCredentials = false;smtpClient.Credentials = credentials; 然後問題解決了!

  SmtpClient smtpClient = new SmtpClient(smtpServerName);       
      System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(smtpUName, smtpUNamePwd); 

      smtpClient.Credentials = credentials; 
      smtpClient.UseDefaultCredentials = false; <-- Set This Line After Credentials 

      smtpClient.Send(mailMsg); 
      smtpClient = null; 
      mailMsg.Dispose(); 
36

修正了一些錯別字在上面的工作代碼:

MailMessage msg = new MailMessage(); 
msg.To.Add(new MailAddress("[email protected]", "SomeOne")); 
msg.From = new MailAddress("[email protected]", "You"); 
msg.Subject = "This is a Test Mail"; 
msg.Body = "This is a test message using Exchange OnLine"; 
msg.IsBodyHtml = true; 

SmtpClient client = new SmtpClient(); 
client.UseDefaultCredentials = false; 
client.Credentials = new System.Net.NetworkCredential("your user name", "your password"); 
client.Port = 587; // You can use Port 25 if 587 is blocked (mine is!) 
client.Host = "smtp.office365.com"; 
client.DeliveryMethod = SmtpDeliveryMethod.Network; 
client.EnableSsl = true; 
try 
{ 
    client.Send(msg); 
    lblText.Text = "Message Sent Succesfully"; 
} 
catch (Exception ex) 
{ 
    lblText.Text = ex.ToString(); 
} 

我有使用上述兩個代碼的Web應用程序,並沒有任何麻煩都工作得不錯。

+0

您運行的是哪個版本的Office 365。我暫時沒有看過這段代碼,但是我們正在準備從小型商業計劃P1移植到企業計劃E1,我想知道我的初始問題是否由我們在P1計劃中引起。 – 2013-08-07 16:10:35

+0

不幸的是,此代碼不再適用於Office 365。出現的錯誤消息是SMTP服務器需要安全連接或客戶端未通過身份驗證。服務器響應是:5.7.57 SMTP;客戶端未通過身份驗證發送匿名郵件來自[HE1PR05CA0133.eurprd05.prod.outlook.com] – 2018-01-30 00:02:35

2

我已經移植了c#代碼,用於對付smtp.google.com:587以通過office365工作,但沒有成功。在使用Ssl之前/之後嘗試了所有的Credential組合,以及幾乎所有在互聯網上提出的建議 - 無法成功(得到5.7.1 ....錯誤)。

終於得到了這條線從某處作爲最後的手段,只是

smtpClient.TargetName = "STARTTLS/smtp.office365.com"; 

自此之前。發送(消息) - 每發送()是大獲成功。

3

Office 365使用兩臺服務器,SMTP服務器和保護擴展服務器。

第一臺服務器是smtp.office365.com(屬性是smtp客戶端的主機),第二臺服務器是STARTTLS/smtp.office365.com(smtp客戶端的屬性TargetName)。另一件事是必須在設置networkcredentials之前放置Usedefaultcredential = false。

client.UseDefaultCredentials = False 
    client.Credentials = New NetworkCredential("[email protected]", "Password") 
    client.Host = "smtp.office365.com" 
    client.EnableSsl = true 
    client.TargetName = "STARTTLS/smtp.office365.com" 
    client.Port = 587 

    client.Send(mail) 
+0

smtp.office365.com是兩個以上的服務器。 – 2016-03-02 14:59:09

5

以下是一些可能在搜索此主題以解答此問題的附註。 (在實施此解決方案之前,請務必閱讀底部的注意事項。)我無法爲MS Office 365訂閱沒有用戶或域的客戶端發送電子郵件。我嘗試通過我的[email protected] 365帳戶嘗試SMTP,但.NET郵件消息的地址是[email protected]。這是當「5.7.1客戶端沒有權限」錯誤彈出爲我。要解決此問題,MailMessage類需要將發件人屬性設置爲我提供的SMTP憑據在O365中「發送」的許可權的電子郵件地址。我選擇使用我的主帳戶電子郵件([email protected]),如下面的代碼所示。請記住,我可以使用任何電子郵件地址我O365帳戶有權限「發送爲」(即[email protected][email protected]等)

using System; 
using System.Net.Mail; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     using (
      MailMessage message = new MailMessage 
      { 
       To = { new MailAddress("[email protected]", "Recipient 1") }, 
       Sender = new MailAddress("[email protected]", "Me"), 
       From = new MailAddress("[email protected]", "Client"), 
       Subject=".net Testing" 
       Body="Testing .net emailing", 
       IsBodyHtml=true, 
      } 
     ) 
     { 
      using (
       SmtpClient smtp = new SmtpClient 
       { 
        Host = "smtp.office365.com", 
        Port = 587, 
        Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"), 
        EnableSsl = true 
       } 
      ) 
      { 
       try { smtp.Send(message); } 
       catch (Exception excp) 
       { 
        Console.Write(excp.Message); 
        Console.ReadKey(); 
       } 
      } 
     } 
     } 
    } 
} 

請注意SmtpClient僅僅是一次性的,並且能夠使用Using塊中的.NET Framework 3.5通過.NET框架2的4
用戶應使用SmtpClient這樣...

SmtpClient smtp = new SmtpClient 
{ 
    Host = "smtp.office365.com", 
    Port = 587, 
    Credentials = new System.Net.NetworkCredential("[email protected]", "Pa55w0rd"), 
    EnableSsl = true 
}; 
try { smtp.Send(message); } 
catch (Exception excp) 
{ 
    Console.Write(excp.Message); 
    Console.ReadKey(); 
} 

生成的電子郵件的標題會是這個樣子:

Authentication-Results: spf=none (sender IP is) 
    [email protected]; 
Received: from MyPC (192.168.1.1) by 
    BLUPR13MB0036.namprd13.prod.outlook.com (10.161.123.150) with Microsoft SMTP 
    Server (TLS) id 15.1.318.9; Mon, 9 Nov 2015 16:06:58 +0000 
MIME-Version: 1.0 
From: Client <[email protected]> 
Sender: Me <[email protected]> 
To: Recipient 1 <[email protected]> 

- 慎 -
注意一些郵件客戶端可以作爲音符顯示的發件人地址。例如Outlook將沿着顯示在閱讀窗格中的頭幾行內容:客戶名義<客戶@ ClientDomain的

我<[email protected]>。com >

但是,只要收件人使用的電子郵件客戶端不是垃圾郵件,就不會影響回覆地址。答覆仍應使用發件人地址。爲了覆蓋所有的基礎,您還可以利用MailMessage.ReplyToList屬性爲客戶提供一切機會來使用正確的回覆地址。

此外,請注意,某些電子郵件服務器可能會拒絕任何發送代表另一家公司選址域所有者策略限制的電子郵件。一定要徹底測試並尋找任何反彈。我可以告訴你,我個人的Hotmail(mail.live.com)電子郵件帳戶是拒絕我代表我的某個客戶發送的郵件,但其他客戶通過罰款。儘管我懷疑它與我的客戶的域名TXT「spf1」記錄有關,但我沒有回答爲什麼它會拒絕代表一個域名與另一個域名發送的電子郵件。也許有人知道可以揭示這個問題?

+0

只是一個說明 - 辦公室365似乎不喜歡添加發件人標籤 – markthewizard1234 2016-11-01 16:09:14

相關問題