通过Exchange Online使用System.Net.Mail发送SMTP电子邮件(Office 365)

Ada*_*art 44 c# exchange-server sendmail system.net.mail office365

我们正在测试新的Office 365测试版,并且我在Exchange Online服务上有一个邮件帐户.现在我正在尝试连接可以从我的测试帐户发送smtp电子邮件的LOB应用程序.

但是,Exchange 365平台需要在端口587上进行TLS加密,并且其"功能" System.Net.Mail不允许隐式SSL加密.

有没有人设法让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);
Run Code Online (Sandbox Code Playgroud)

小智 47

修复了上面工作代码中的一些拼写错误:

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();
}
Run Code Online (Sandbox Code Playgroud)

我有两个使用上述代码的Web应用程序,并且都可以正常工作而没有任何问题.

  • 遗憾的是,此代码对Office 365不再有效.出现的错误消息是SMTP服务器需要安全连接或客户端未经过身份验证.服务器响应是:5.7.57 SMTP; 客户未通过身份验证,以便在MAIL FROM [HE1PR05CA0133.eurprd05.prod.outlook.com]期间发送匿名邮件 (14认同)

Jir*_*ong 17

在 2020 年,这些代码似乎返回异常为

System.Net.Mail.SmtpStatusCode.MustIssueStartTlsFirstSMTP 服务器需要安全连接或客户端未通过身份验证。服务器响应为:5.7.57 SMTP;在 MAIL FROM 期间,客户端未通过身份验证发送匿名邮件

这段代码对我有用。

            using (SmtpClient client = new SmtpClient()
            {
                Host = "smtp.office365.com",
                Port = 587,
                UseDefaultCredentials = false, // This require to be before setting Credentials property
                DeliveryMethod = SmtpDeliveryMethod.Network,
                Credentials = new NetworkCredential("alias@fulldomain.com", "password"), // you must give a full email address for authentication 
                TargetName = "STARTTLS/smtp.office365.com", // Set to avoid MustIssueStartTlsFirst exception
                EnableSsl = true // Set to avoid secure connection exception
            })
            {

                MailMessage message = new MailMessage()
                {
                    From = new MailAddress("alias@fulldomain.com"), // sender must be a full email address
                    Subject = subject,
                    IsBodyHtml = true,
                    Body = "<h1>Hello World</h1>",
                    BodyEncoding = System.Text.Encoding.UTF8,
                    SubjectEncoding = System.Text.Encoding.UTF8,

                };
                var toAddresses = recipients.Split(',');
                foreach (var to in toAddresses)
                {
                    message.To.Add(to.Trim());
                }

                try
                {
                    client.Send(message);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }
Run Code Online (Sandbox Code Playgroud)


The*_*ude 13

快速回答:FROM地址必须与您发送的帐户完全匹配,否则您将收到错误5.7.1客户端无权作为此发件人发送.

我的猜测是使用您的Office 365帐户阻止电子邮件欺骗,否则您可以发送为sballmer@microsoft.com.

另一件要尝试的是在身份验证中,用域填写第三个字段,比如

Dim smtpAuth = New System.Net.NetworkCredential(
    "TheDude", "hunter2password", "MicrosoftOffice365Domain.com")
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,请仔细检查您是否可以登录该帐户:https: //portal.microsoftonline.com

还有一点需要注意的是,您的防病毒解决方案可能阻止对端口25和587的编程访问,作为反垃圾邮件解决方案.诺顿和迈克菲可能会默默地阻止对这些端口的访问.只有启用Mail和Socket调试才能让您注意到它(见下文).

最后要注意的是,Send方法是异步的.如果你打电话

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>
Run Code Online (Sandbox Code Playgroud)

  • 嘿,是的,那是对红色模因的旧参考.我的密码是***************.Src:http://ars.userfriendly.org/cartoons/?id = 199190814 (2认同)

小智 9

Office 365 使用两台服务器,smtp 服务器和保护扩展服务器。

第一个服务器是 smtp.office365.com(smtp 客户端的属性主机),第二个服务器是 STARTTLS/smtp.office365.com(smtp 客户端的属性 TargetName)。另一件事是必须在设置网络凭据之前放置 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)
Run Code Online (Sandbox Code Playgroud)


小智 6

你见过这个吗? 使用Smtp.mail.microsoftonline.com发送电子邮件

设置凭据后设置UseDefaultCredentials将重置您的凭据属性.


Sha*_*eLS 6

以下是一些可能正在搜索此主题以获得此问题的答案的旁注.(在实施此解决方案之前,请务必阅读底部的注意事项.)我无法为我的MS Office 365订阅没有用户或域的客户端发送电子邮件.我试图通过我的Me@MyDomain.com 365帐户进行SMTP,但.NET邮件是从Client@ClientDomain.com发送的.这是为我弹出"5.7.1客户端没有权限"错误的时候.要解决此问题,MailMessage类需要将Sender属性设置为我提供的SMTP凭据在O365中具有"发送为"权限的电子邮件地址.我选择使用我的主帐户电子邮件(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();
               }
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意SmtpClient只是一次性的,能够使用.NET Framework 4中的使用块
.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();
}
Run Code Online (Sandbox Code Playgroud)

生成的电子邮件标题将如下所示:

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>  
Run Code Online (Sandbox Code Playgroud)

- 要小心 -
请注意,某些邮件客户端可能会将发件人地址显示为注释.例如,Outlook将在阅读窗格的标题中沿着这些行显示一些内容:

我<Me@MyDomain.com>代表客户<Client@ClientDomain.com>

但是,只要收件人使用的电子邮件客户端不是完全垃圾,这不应影响回复地址.回复仍应使用发件人地址.为了覆盖所有基础,您还可以使用MailMessage.ReplyToList属性为客户端提供使用正确回复地址的每个机会.

此外,请注意,某些电子邮件服务器可能会拒绝任何代表域所有者策略限制的另一家公司代表发送的电子邮件.一定要彻底测试并寻找任何反弹.我可以告诉你,我的个人Hotmail(mail.live.com)电子邮件帐户将拒绝我代表我的某个客户发送的邮件,但其他客户端会通过罚款.虽然我怀疑它与我的客户的域TXT"spf1"记录有关,但我没有答案为什么它会拒绝代表一个域发送的电子邮件而不是另一个域.也许知道的人可以对这个问题有所了解?


小智 5

我已经将用于处理 smtp.google.com:587 的 C# 代码移植到通过 Office365 工作,但没有成功。尝试了使用 Ssl 之前/之后的所有凭据组合以及互联网上提出的几乎所有建议 - 没有成功(出现 5.7.1 .... 错误)。

终于在 .Send(message) 之前从某个地方得到了这一行作为最后的手段

smtpClient.TargetName = "STARTTLS/smtp.office365.com";
Run Code Online (Sandbox Code Playgroud)

从那时起 - 每次 send() 都取得了巨大的成功。