我使用SmtpClient
库使用以下内容发送电子邮件:
SmtpClient client = new SmtpClient();
client.Host = "hostname";
client.Port = 465;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
client.Credentials = new NetworkCredential("User", "Pass);
client.Send("from@hostname", "to@hostname", "Subject", "Body");
代码在我的测试环境中运行良好,但是当我使用生产SMTP服务器时,代码失败并显示SmtpException
“发送邮件失败”。内部IOException
“无法从传输连接中读取数据:net_io_connectionclosed”。
我已经确认防火墙不是问题。端口在客户端和服务器之间打开很好。我不确定还有什么可能引发这个错误。
答案 0 :(得分:160)
编辑:Super Redux版本
尝试端口587而不是465.端口465在技术上已弃用。
经过一堆数据包嗅探后,我发现了它。首先,这是简短的回答:
.NET SmtpClient
仅支持通过STARTTLS进行加密。如果设置了EnableSsl
标志,则服务器必须使用STARTTLS响应EHLO,否则将引发异常。有关详细信息,请参阅MSDN文档。
其次,为将来偶然发现此问题的人提供快速的SMTP历史课程:
当天,当服务还希望提供加密时,他们会被分配一个不同的端口号,并且在该端口号上,他们立即启动了SSL连接。随着时间的推移,他们意识到为一项服务浪费两个端口号是愚蠢的,他们设计了一种服务方式,允许使用STARTTLS在同一端口上进行明文和加密。通信将以明文开始,然后使用STARTTLS命令升级到加密连接。 STARTTLS成为SMTP加密的标准。不幸的是,由于在实施新标准时总会发生这种情况,因此存在与所有客户端和服务器兼容的大杂烩。
在我的情况下,我的用户试图将软件连接到强制立即进行SSL连接的服务器,这是Microsoft在.NET中不支持的遗留方法。
答案 1 :(得分:16)
将端口从465更改为587,它将起作用。
答案 2 :(得分:15)
对于任何偶然发现此帖子寻找解决方案并且您已通过Azure设置SMTP sendgrid的人。
用户名不是您在azure中创建sendgrid对象时设置的用户名。要查找您的用户名;
希望这有帮助!
答案 3 :(得分:7)
您可能还需要更改不太安全的应用程序"设置您的Gmail帐户。 EnableSsl,使用端口587并启用"安全性较低的应用程序"。如果您谷歌的安全性较低的应用程序部分有谷歌帮助页面,将链接到您的帐户页面。这是我的问题,但由于上面的所有答案,现在一切正常。
答案 4 :(得分:4)
我尝试了以上所有答案,但仍然使用Office 365帐户遇到此错误。当允许使用不太安全的应用程序时,该代码似乎可以与Google帐户和smtp.gmail.com一起正常工作。
还有其他可以尝试的建议吗?
这是我正在使用的代码
(SoapFault): Authorization Required
更新以及如何解决:
通过将Smtp客户端更改为Mailkit解决了问题。由于安全性问题,现在不建议Microsoft使用System.Net.Mail Smtp客户端,而应该使用MailKit。使用Mailkit给我提供了更清晰的错误消息,我可以理解这些错误消息是找到问题(许可证问题)的根本原因。您可以通过以Nuget程序包的形式下载Mailkit。
阅读有关Smtp客户端的文档,以获取更多信息: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2
这是我如何通过MailKit实现SmtpClient
int port = 587;
string host = "smtp.office365.com";
string username = "smtp.out@mail.com";
string password = "password";
string mailFrom = "noreply@mail.com";
string mailTo = "to@mail.com";
string mailTitle = "Testtitle";
string mailMessage = "Testmessage";
using (SmtpClient client = new SmtpClient())
{
MailAddress from = new MailAddress(mailFrom);
MailMessage message = new MailMessage
{
From = from
};
message.To.Add(mailTo);
message.Subject = mailTitle;
message.Body = mailMessage;
message.IsBodyHtml = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Host = host;
client.Port = port;
client.EnableSsl = true;
client.Credentials = new NetworkCredential
{
UserName = username,
Password = password
};
client.Send(message);
}
答案 5 :(得分:3)
您的SMTP库是否支持加密连接?邮件服务器可能期望安全的TLS连接,因此在没有TLS握手的情况下关闭连接
答案 6 :(得分:2)
如果您在同一个盒子上使用SMTP服务器并且您的SMTP绑定到IP地址而不是“任何已分配”,则可能会失败,因为它尝试使用SMTP是的IP地址(如127.0.0.1)目前没有工作。
答案 7 :(得分:1)
如果以上所有解决方案都不适合您,请尝试将以下文件更新到您的服务器(通过发布我的意思是,之前的构建会有所帮助)。
bin-> projectname.dll
更新后,您将看到此错误。 因为我用这个解决方案解决了。
答案 8 :(得分:1)
为了提升jocull在评论中提到的内容,我正在执行此线程中提到的所有内容并删除……因为我的循环在不断地重复进行;在第一次通过循环后,有时会失败。总是在循环中第一次工作。
要清楚:循环包括创建SmtpClient,然后使用正确的数据进行发送。 SmtpClient是在try / catch块内创建的,以捕获错误并确保对象在循环底部之前被破坏。
在我的情况下,解决方案是确保SmtpClient在每次循环后都被处置(通过using()语句或通过手动处置)。即使SmtpClient对象在循环中被隐式破坏,.NET似乎也会留下东西来与下次尝试冲突。
答案 9 :(得分:1)
删除
client.UseDefaultCredentials = false;
似乎为我解决了。
答案 10 :(得分:0)
如果您正在使用 Sendgrid 并且收到此错误,那是因为 sendgrid 不再允许基本身份验证。我们需要创建 API 密钥并将它们用作 NetworkCredential。 username="apikey" 密码将是您的 API 密钥 参考 - https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api
答案 11 :(得分:0)
我最初的问题是关于间歇性发送失败。例如。第一个 Send()
成功,第二个 Send()
失败,第三个 Send()
成功。起初我以为我没有正确处理。所以我求助于using()
。
反正后来加了UseDefaultCredentials = false
,Send()终于稳定了。
不知道为什么。
答案 12 :(得分:0)
在使用smtp.office365.com时,使用端口587和SSL时,我遇到了这个问题。我能够使用portal.office.com登录到该帐户,并且可以确认该帐户具有许可证。但是,当我触发代码发送电子邮件时,我不断收到net_io_connectionclosed错误。
花了一些时间弄清楚了,但Exchange管理员找到了罪魁祸首。我们使用的是O365,但Exchange服务器处于混合环境中。尽管我们尝试使用的帐户已同步到Azure AD并具有有效的O365许可证,但是由于某些原因,邮箱仍驻留在混合Exchange服务器上-而不是在线Exchange。在交换管理员使用“ Move-Mailbox”命令将邮箱从混合交换服务器移动到O365之后,我们可以使用该代码通过o365发送电子邮件。
答案 13 :(得分:0)
如果您的邮件服务器是Gmail(smtp.google.com),则在达到邮件限制时会出现此错误。 Gmail允许每24小时通过SMTP发送最多2000条消息。
答案 14 :(得分:0)
对于我来说,Web服务器IP在邮件服务器上已被阻止,您的托管公司需要将其取消阻止并将其列入白名单。另外,使用端口587。
答案 15 :(得分:0)
将端口号从465更改为587
答案 16 :(得分:0)
在我的情况下,客户忘记在其SMTP设置中添加新的IP地址。在设置smtp的服务器中打开IIS 6.0,右键单击Smtp虚拟服务器,选择“属性”,“访问”选项卡,单击“连接”,添加新服务器的IP地址。然后单击中继,还添加新服务器的IP地址。这解决了我的问题。
答案 17 :(得分:0)
此错误非常笼统,可能是由于多种原因引起的,例如 邮件服务器不正确。 一些托管公司使用mail.domainname格式。 如果您仅使用域名,它将无法正常工作。 检查凭证 主机名 用户名密码(如果需要) 与托管公司联系。
<smtp from="info@india.uu.com">
<!-- Uncomment to specify SMTP settings -->
<network host="domain.com" port="25" password="Jin@" userName="info@india.xx.com"/>
</smtp>
</mailSettings>
答案 18 :(得分:0)
对于Outlook,请使用以下不会给我错误的设置
SMTP服务器名称smtp-mail.outlook.com
SMTP端口587
答案 19 :(得分:0)
//Try this out... Port 465 is not there anymore for use
string emailFrom = "sender email here";
string recieverEmail ="reciever email here";
string subject = "subject here";
string body = "message here";
MailMessage maile = new MailMessage(emailFrom, recieverEmail, subject,body);
SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
client.Credentials = new System.Net.NetworkCredential("senders gmail account username here", "senders gmail account password here");
client.EnableSsl = true;
答案 20 :(得分:0)
试试这个:这是我用来向多个用户发送电子邮件的代码。
public string gmail_send()
{
using (MailMessage mailMessage =
new MailMessage(new MailAddress(toemail),
new MailAddress(toemail)))
{
mailMessage.Body = body;
mailMessage.Subject = subject;
try
{
SmtpClient SmtpServer = new SmtpClient();
SmtpServer.Credentials =
new System.Net.NetworkCredential(email, password);
SmtpServer.Port = 587;
SmtpServer.Host = "smtp.gmail.com";
SmtpServer.EnableSsl = true;
mail = new MailMessage();
String[] addr = toemail.Split(','); // toemail is a string which contains many email address separated by comma
mail.From = new MailAddress(email);
Byte i;
for (i = 0; i < addr.Length; i++)
mail.To.Add(addr[i]);
mail.Subject = subject;
mail.Body = body;
mail.IsBodyHtml = true;
mail.DeliveryNotificationOptions =
DeliveryNotificationOptions.OnFailure;
// mail.ReplyTo = new MailAddress(toemail);
mail.ReplyToList.Add(toemail);
SmtpServer.Send(mail);
return "Mail Sent";
}
catch (Exception ex)
{
string exp = ex.ToString();
return "Mail Not Sent ... and ther error is " + exp;
}
}
}
答案 21 :(得分:-1)
准备: 1. HostA是具有默认端口25的SMTP虚拟服务器 2. HostB是一个工作站,我在该工作站上使用SmtpClient发送邮件 并模拟不稳定的网络 I use clumsy
案例1 如果HostB为2008R2,则给出 当我发送电子邮件时。 然后会发生此问题。
案例2 如果HostB是2012或更高版本,则给出 当我发送电子邮件时。 然后邮件已发送出去。
结论:根本原因与Windows Server 2008R2有关。