我在Microsoft网站上读到SmtpClient已经过时,他们建议使用MailKit进行替换。
我正在编写一个应用程序来使用 MailKit。
这是我到目前为止所拥有的:
// *************** SEND EMAIL *******************
using (var client = new MailKit.Net.Smtp.SmtpClient())
{
//accept all SSL certificates
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.IsSslEnabled);
if (emailSettings.IsAuthenticationRequired)
{
// Note: only needed if the SMTP server requires authentication
client.Authenticate(emailSettings.SmtpUsername, emailSettings.SmtpPassword);
}
// timeout = 20 seconds
client.Timeout = 20000;
client.Send(message);
client.Disconnect(true);
}
当我设置这部分时:
client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.IsSslEnabled);
最后一个参数是bool useSSL
,我将其设置为 true。我的电子邮件服务器由Rackspace托管,所以我知道它使用SSL。 当我将此选项设置为 true 时,它无法发送,但如果我将此选项设置为 false,它会发送正常。
此行不应该捕获证书类型:
client.ServerCertificateValidationCallback
如果是这样,为什么连接上的useSSL
不起作用?我需要将useSSL
设置为 false 吗?当我有上面的行时,我对useSSL
的工作原理感到困惑。
邮件协议(SMTP、IMAP 和 POP3)都有 2 种不同的 SSL 执行方式。
System.Net.Mail.SmtpClient只实现了对SSLSTARTTLS
方式的支持,而MailKit同时实现了这两种方式。
当您在 MailKit 的Connect
方法中将useSsl
指定为true
时,它假定您打算使用 SSL 包装的连接(与STARTTLS
不同)。
为了不那么令人困惑,MailKit 有一个Connect
方法,该方法采用SecureSocketOptions
参数而不是bool
。
选项如下:
None
:不要使用任何形式的SSL(或TLS)。Auto
:根据指定的端口自动决定使用哪种类型的SSL模式。注意:仅当端口是标准定义的端口(例如,SMTP 为 25、587 或 465)时,这才有效。SslOnConnect
:这指定 MailKit 应通过 SSL 包装的连接进行连接。StartTls
:使用STARTTLS
方法进行 SSL/TLS 加密。如果服务器不支持STARTTLS
命令,请中止连接。StartTlsWhenAvailable
:如果服务器支持 SSL/TLS 加密,请使用STARTTLS
方法,否则继续使用未加密的通道。
由于您使用的是 SMTP,因此您可能会发现这很有用:
端口25
是用于 SMTP 的原始端口,它最初仅支持未加密的通信。
后来,管理员和用户要求 SSL 加密,因此管理员和邮件客户端开始在端口465
上支持 SSL 包装的连接,因为这对管理员来说非常容易(无需升级服务器软件,不支持 SSL 包装连接的客户端可以继续在端口25
上连接)。
几年后,邮件协议作者引入了 IMAP、SMTP 和 POP3 的STARTTLS
命令扩展(嗯,对于 POP3,命令是STLS
,但在其他方面是相同的),如果客户端支持它,他们可以选择使用它。此扩展仅在原始(非 SSL 包装)端口上有意义。
如今,STARTTLS
是加密客户端和邮件服务器之间通信的首选方法,但SSL包装的端口仍然被广泛使用。
MailKit 对待端口587
与对待25
相同。换句话说,它将端口25
和587
视为纯文本连接端口,但如果通过STARTTLS
请求这样做,它将切换到 SSL/TLS。