60

我们正在测试新的 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);
4

8 回答 8

65

修复了上面工作代码中的一些错别字:

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 应用程序,它们都可以正常工作,没有任何问题。

于 2013-08-02T05:10:42.867 回答
27

在 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);
                }
            }
于 2020-04-08T04:17:46.007 回答
15

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

我的猜测是,这可以防止使用您的 Office 365 帐户进行电子邮件欺骗,否则您可以通过 sballmer@microsoft.com 发送电子邮件。

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

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

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

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

最后要注意的一件事,Send方法是Asynchronous。如果你打电话

处置
在您致电发送后,您很可能会在发送邮件之前关闭您的连接。让您的 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>
于 2012-07-13T04:31:04.300 回答
10

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)
于 2015-07-24T08:31:46.357 回答
8

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

在设置 Credentials 之后设置 UseDefaultCredentials 将重置您的 Credentials 属性。

于 2011-11-01T13:25:05.767 回答
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();
               }
            }
         }
      }
   }
}

请注意 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 属性为客户端提供使用正确回复地址的每一个机会。

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

于 2015-11-09T16:01:05.320 回答
4

我已将用于对抗 smtp.google.com:587 的 c# 代码移植到通过 office365 工作但没有成功。在使用 Ssl 之前/之后尝试了所有 Credential 组合以及在 Internet 上提出的几乎所有建议 - 没有成功(得到 5.7.1 .... 错误)。

最后从某处得到这条线作为最后的手段,就在 .Send(message)

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

从那时起 - 每个 send() 都是巨大的成功。

于 2014-06-11T22:24:06.030 回答
-2

最后,工作!

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();
于 2012-11-28T00:21:33.747 回答