在.NET中测试使用Microsoft Office 365发送SMTP邮件

17

我在Exchange Online服务上拥有一个邮件帐户。现在我正在尝试测试是否能够通过C#应用程序向客户(在各种域和Microsoft Office 365上)发送电子邮件。

我尝试实现以下代码,但是我遇到了错误

"The remote certificate is invalid according to the validation procedure."

MailMessage mail = null;                
mail = new MailMessage();

string[] strToList = "abc@gmail.com"              
foreach (string strID in strToList)
{
    if (strID != null)
    {
        mail.To.Add(new MailAddress(strID));
    }
}

mail.From = "demo@onmicrosoft.com";
mail.Subject = "testing"
mail.IsBodyHtml = true;
mail.Body = "mail body";

SmtpClient client = new SmtpClient("smtp.outlook.office365.com");
client.Port = 587;
client.EnableSsl = true;
client.UseDefaultCredentials = false;
NetworkCredential cred = new System.Net.NetworkCredential("demo@onmicrosoft.com", "mypassword");
client.Credentials = cred;
client.Send(mail);

请告诉我是否有做错什么。非常感谢。


尝试一下这个:http://www.softdeveloperszone.com/2013/04/send-email-through-office-365-outlook.html。对我有用。 - chamara
8个回答

15

这对我有效 (从来源编辑而来)


   ThreadPool.QueueUserWorkItem(t =>
            {
                SmtpClient client = new SmtpClient("smtp.office365.com",587);
                client.EnableSsl = true;
                client.Credentials = new System.Net.NetworkCredential("xxx@yyy.com", "password");
                MailAddress from = new MailAddress("xxx@yyy.com", String.Empty, System.Text.Encoding.UTF8);
                MailAddress to = new MailAddress("xxx@yyy.com");
                MailMessage message = new MailMessage(from, to);
                message.Body = "The message I want to send.";
                message.BodyEncoding = System.Text.Encoding.UTF8;
                message.Subject = "The subject of the email";
                message.SubjectEncoding = System.Text.Encoding.UTF8;
                // Set the method that is called back when the send operation ends.
                client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
                // The userState can be any object that allows your callback 
                // method to identify this send operation.
                // For this example, I am passing the message itself
                client.SendAsync(message, message);
            });

        private static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
        {
            // Get the message we sent
            MailMessage msg = (MailMessage)e.UserState;

            if (e.Cancelled)
            {
                // prompt user with "send cancelled" message 
            }
            if (e.Error != null)
            {
                // prompt user with error message 
            }
            else
            {
                // prompt user with message sent!
                // as we have the message object we can also display who the message
                // was sent to etc 
            }

            // finally dispose of the message
            if (msg != null)
                msg.Dispose();
        }

有人知道是否可以在不输入明文密码的情况下完成这个操作吗? - TizzyFoe
我在回调函数中没有收到错误信息,但是邮件没有发送?你能帮帮我吗? - Peter
你有 e.Error = null 吗?e.Cancelled = true/false?试试 client.EnableSsl = false; - Zakos

6
在某些情况下,TLS身份验证可能会导致在从C#使用smtp.office365.com作为SMTP时出现问题。在Send(msg)语句之前尝试以下行(覆盖.TargetName):
client.TargetName = "STARTTLS/smtp.office365.com";

这个对我有效。

这对我解决了问题 - 我在许多地方都使用了这个问题中的常规代码,但是在某个站点上,如果没有添加这个TargetName值,我就无法使事情顺利进行。谢谢!! - Ian Yates

6

这也是发送邮件的最佳方式。我在我的项目中尝试过,效果很好。

 SmtpClient client = new SmtpClient("smtp.office365.com", 587);
        client.EnableSsl = true;
        client.Credentials = new System.Net.NetworkCredential("From@mail.com", "sdsd@12345");
        MailAddress from = new MailAddress("From Address Ex From@mail.com", String.Empty, System.Text.Encoding.UTF8);
        MailAddress to = new MailAddress("From Address Ex To@mail.com");
        MailMessage message = new MailMessage(from, to);
        message.Body = "This is your body message";
        message.BodyEncoding = System.Text.Encoding.UTF8;
        message.Subject = "Subject";
        message.SubjectEncoding = System.Text.Encoding.UTF8;

        client.Send(message);

3

尝试使用smtp.office365.com而不是smtp.outlook.office365.com


2
尝试使用:
ServicePointManager.ServerCertificateValidationCallback = 
    (sender, certificate, chain, sslPolicyErrors) => true;

这段代码将允许你接受无效的证书。

正如Ori Nachum在评论中提到的那样:这是非常糟糕的做法,只应在测试目的下使用。这是一种安全风险!


当我尝试上述操作时,我遇到了另一个异常:“SMTP服务器需要安全连接或客户端未经身份验证。服务器响应为:5.7.1 客户端未经身份验证”。 - user166013
@RowlandShaw 你有检查过这个网址吗?https://dev59.com/WGEi5IYBdhLWcg3w2POB - Piotr Stapp
应该注意到这是一种不良的做法,只应该用于测试目的。这是一个重大的安全风险。 - Ori Nachum

1
尝试设置:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

它将确保服务的SecurityPoint使用TLS。
请注意,这里提供了一个设置答案。
ServicePointManager.ServerCertificateValidationCallback = 
    (sender, certificate, chain, sslPolicyErrors) => true;

这个工具可能适用于测试目的,但是它是一个重大的安全风险
不要在生产环境或使用生产账户时使用。


1

错误

SMTP服务器需要安全连接或客户端未经过身份验证。服务器响应是:5.7.1 客户端未经过身份验证

通常发生在相关用户帐户密码过期或帐户被锁定时。如果不违反公司密码策略,请尝试在Active Directory中设置“永不过期的用户密码”。这在我使用o365 Exchange Online A/c进行测试时发生。


我专门设置了一个新用户来通过SMTP登录。我遇到了这个错误,因为在第一次登录时,需要用户更改密码。这让我困惑了一段时间! - johnnycardy

1
var Client = new SmtpClient("smtp.office365.com", 587);
Client.EnableSsl = true;
Client.Credentials = new System.Net.NetworkCredential("mail", "pass");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

我成功地使用代码发送了邮件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接