使用System.Net.Mail通过Exchange Online发送SMTP电子邮件(Office 365)
我们正在testing新的Office 365testing版,并且在Exchange Online服务上有一个邮件帐户。 现在我试图连接一个LOB应用程序,可以从我的testing帐户发送smtp电子邮件。
但是,Exchange 365平台需要在端口587上进行TLSencryption,并且System.Net.Mail
有一个“function”,不允许隐式SSLencryption。
有没有人设法让C#通过这个平台发送邮件?
我有以下基本的代码,应该发送邮件 – 任何意见,将不胜感激。
SmtpClient server = new SmtpClient("ServerAddress"); server.Port = 587; server.EnableSsl = true; server.Credentials = new System.Net.NetworkCredential("username@mydomain.com", "password"); server.Timeout = 5000; server.UseDefaultCredentials = false; MailMessage mail = new MailMessage(); mail.From = new MailAddress("recipent@anyaddress"); mail.To.Add("username@mydomain.com"); mail.Subject = "test out message sending"; mail.Body = "this is my message body"; mail.IsBodyHtml = true; server.Send(mail);
修正了上面工作代码中的一些错别字:
MailMessage msg = new MailMessage(); msg.To.Add(new MailAddress("someone@somedomain.com", "SomeOne")); msg.From = new MailAddress("you@yourdomain.com", "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应用程序,都没有任何问题的罚款。
快速回答:FROM地址必须与您发送的帐户完全匹配,否则您将收到错误5.7.1客户端无权发送此发件人。
我的猜测是,防止电子邮件与您的Office 365帐户欺骗,否则您可能能够发送作为sballmer@microsoft.com。
另一个要尝试的是在身份validation,填写与域的第三个领域,如
Dim smtpAuth = New System.Net.NetworkCredential( "TheDude", "hunter2password", "MicrosoftOffice365Domain.com")
如果这不起作用,请仔细检查您是否可以login该帐户: https : //portal.microsoftonline.com
还有一点需要注意的是,您的防病毒解决scheme可能会阻止程序化访问端口25和587作为反垃圾邮件解决scheme。 诺顿和McAfee可能会默默阻止对这些端口的访问。 只有启用邮件和套接字debugging才能让你注意到(见下文)。
最后要注意的是, Send方法是asynchronous的 。 如果你打电话
部署
在您致电发送之后,在发送邮件之前,您很可能会closures您的连接。 让你的smtpClient实例监听OnSendCompleted事件,并从那里调用dispose。 您必须使用SendAsync方法,Send方法不引发此事件。
详细的答案:与Visual Studio(VB.NET或C#无关紧要),我做了一个简单的forms与创build邮件消息,类似于上面的button。 然后我将其添加到application.exe.config(在我的项目的bin / debug目录中)。 这使输出选项卡具有详细的debugging信息。
<?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>
这里有一些可能正在寻找这个问题的答案这个问题的附注。 (请务必在实施此解决scheme前阅读注意事项)。我无法为MS Office 365订阅没有用户或域的客户端发送电子邮件。 我试图通过我的Me@MyDomain.com 365帐户SMTP,但.NET邮件消息是从Client@ClientDomain.com寻址 。 这是当“5.7.1客户端没有权限”错误popup为我。 为了补救, MailMessage类需要将发件人属性设置为一个电子邮件地址,我提供的SMTP凭据有权在O365“发送”。 我select使用我的主要帐户电子邮件( Me@MyDomain.com ),如下面的代码所示。 请记住,我可以使用任何电子邮件地址我的O365帐户有权“发送”(即Support@MyDomain.com,no-reply@MyDomain.com等)
using System; using System.Net.Mail; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { using ( MailMessage message = new MailMessage { To = { new MailAddress("Recipient1@Recipient1Domain.com", "Recipient 1") }, Sender = new MailAddress("Me@MyDomain.com", "Me"), From = new MailAddress("Client@ClientDomain.com", "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("Me@MyDomain.com", "Pa55w0rd"), EnableSsl = true } ) { try { smtp.Send(message); } catch (Exception excp) { Console.Write(excp.Message); Console.ReadKey(); } } } } } }
请注意SmtpClient只是一次性的,能够使用.NET Framework 4中的Using块
.NET Framework 2到3.5的用户应该使用SmtpClient。
SmtpClient smtp = new SmtpClient { Host = "smtp.office365.com", Port = 587, Credentials = new System.Net.NetworkCredential("Me@MyDomain.com", "Pa55w0rd"), EnableSsl = true }; try { smtp.Send(message); } catch (Exception excp) { Console.Write(excp.Message); Console.ReadKey(); }
结果电子邮件的标题将如下所示:
Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Me@MyDomain.com; 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 <Client@ClientDomain.com> Sender: Me <Me@MyDomain.com> To: Recipient 1 <Recipient1@Recipient1Domain.com>
– 要小心 –
请注意,某些邮件客户端可能会将发件人地址显示为备注。 例如Outlook将在阅读窗格的标题中沿着这些行显示一些内容:
我<Me@MyDomain.com>代表客户<Client@ClientDomain.com>
但是,只要收件人使用的电子邮件客户端不是垃圾邮件,就不会影响回复地址。 答复仍应使用发件人地址。 为了覆盖您的所有基础,您还可以利用MailMessage.ReplyToList属性为客户提供一切机会来使用正确的回复地址。
此外,请注意,有些电子邮件服务器可能会拒绝任何发送给代表另一家公司的域名所有者策略限制的电子邮件。 一定要彻底testing,并寻找任何反弹。 我可以告诉你,我个人的Hotmail(mail.live.com)电子邮件帐户是拒绝我代表我的某个客户发送的邮件,但其他客户通过罚款。 虽然我怀疑它与我的客户的域TXT“spf1”logging有关,但我没有答案,为什么它会拒绝代表一个域发送的电子邮件。 也许有人知道可以揭示这个问题?
你见过这个吗? 使用Smtp.mail.microsoftonline.com发送电子邮件
设置凭证后设置UseDefaultCredentials将重置您的凭证属性。
Office 365使用两台服务器,SMTP服务器和保护扩展服务器。
第一台服务器是smtp.office365.com(smtp客户端的属性主机),第二台服务器是STARTTLS / smtp.office365.com(smtp客户端的属性TargetName)。 另一件事是在设置networkcredentials之前,必须放置Usedefaultcredential = false。
client.UseDefaultCredentials = False client.Credentials = New NetworkCredential("user@domain.com", "Password") client.Host = "smtp.office365.com" client.EnableSsl = true client.TargetName = "STARTTLS/smtp.office365.com" client.Port = 587 client.Send(mail)
我已经移植了C#代码用于对付smtp.google.com:587通过office365工作没有成功。 在使用Ssl之前/之后尝试了所有的证书组合,几乎每一个在互联网上的build议 – 没有成功(得到5.7.1 ….错误)。
最后从某个地方得到这条线,作为最后的手段,就在之前。发送(消息)
smtpClient.TargetName = "STARTTLS/smtp.office365.com";
从那以后 – 每个send()都是大获成功的。
最后,作品!
把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();