您遇到的问题是SmtpClient正在使用服务器拒绝SMTP的主机名/域字符串发出HELO
或EHLO
命令。
我显然不知道Microsoft的SmtpClient实现的内部逻辑,但是我怀疑您可能在NAT的后面,这意味着SmtpClient无法解析您的计算机在世界范围内可见的完全限定域名。它只能解析“内部网络”上计算机的FQDN(实际上,它甚至可能无法解析为实际的FQDN,它可能必须满足内部网络IP地址)。
所以... SmtpClient可能正在发送类似EHLO [192.168.1.100]
(或任何本地IP)的消息,并且服务器拒绝了它,因为那不是它从其接收数据包的IP地址。
您需要做的是通过访问http://www.whatismyip.com/等站点或使用http://www.displaymyhostname.com/等站点检测到的主机名来找到外部IP地址。
为了说明我在说什么,这里有一个演示程序:
using System; using System.Net; using System.Linq; using System.Net.Sockets; using System.Collections.Generic; using System.Net.NetworkInformation; namespace LocalHostName { class Program { static void Main (string[] args) { var ipAddresses = Dns.GetHostAddresses ("www.google.com"); Socket socket; for (int i = 0; i < ipAddresses.Length; i++) { socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { socket.Connect (ipAddresses[i], 80); Console.WriteLine ("LocalEndPoint: {0}", socket.LocalEndPoint); break; } catch { socket.Dispose (); socket = null; if (i + 1 == ipAddresses.Length) throw; } } Console.ReadLine (); } } }
它打印出的任何IP地址都可能是SmtpClient在其HELO
/ EHLO
命令中使用的IP地址。
坏消息是System.Net.Mail.SmtpClient无法解决此问题。
好消息是,我节省了15%的汽车保险...嗯,我的意思是,我已经编写了自己的电子邮件库,名为MimeKit和MailKit,可以解决此问题。
还有一些好消息是,您可以轻松地将System.Net.Mail.MailMessage对象转换为MimeKit.MimeMessage对象(尽管显然,最好完全切换到MimeKit和MailKit)。
var mimeMessage = (MimeMessage) mailMessage;
这是使用MimeKit和MailKit重新编写的SMTPMailHelper类的样子:
using System; using MimeKit; using MailKit.Net.Smtp; public class SMTPMailHelper { const string SMTPServer = "mail.mydomain.com"; const string SMTPUserId = "myemail@mydomain.com"; const string SMTPPassword = "MyPasswordHidden"; const int SMTPPort = 25; public static void SendMail(string sendFrom, string sendTo, string subject, string body) { MimeMessage message = new MimeMessage (); TextPart text; message.From.Add (new MailboxAddress ("", sendFrom)); message.To.Add (new MailboxAdress ("", sendTo)); message.Subject = subject; if (body.ToLower ().Contains ("")) text = new TextPart ("html") { Text = text }; else text = new TextPart ("plain") { Text = text }; message.Body = text; using (var smtp = new SmtpClient ()) { // use the IP address gotten from http://www.whatismyip.com/ // or the hostname gotten from http://www.displaymyhostname.com/ smtp.LocalDomain = "c-24-71-150-91.hsd1.ga.comcast.net"; smtp.Connect (SMTPServer, SMTPPort, false); smtp.Authenticate (SMTPUserId, SMTPPassword); smtp.Send (message); smtp.Disconnect (true); } } }
重要的是将SmtpClient的LocalDomain属性设置为的字符串。
您遇到的问题是SmtpClient正在使用服务器拒绝SMTP的主机名/域字符串发出HELO
或EHLO
命令。
我显然不知道Microsoft的SmtpClient实现的内部逻辑,但是我怀疑您可能在NAT的后面,这意味着SmtpClient无法解析您的计算机在世界范围内可见的完全限定域名。它只能解析“内部网络”上计算机的FQDN(实际上,它甚至可能无法解析为实际的FQDN,它可能必须满足内部网络IP地址)。
所以... SmtpClient可能正在发送类似EHLO [192.168.1.100]
(或任何本地IP)的消息,并且服务器拒绝了它,因为那不是它从其接收数据包的IP地址。
您需要做的是通过访问http://www.whatismyip.com/等站点或使用http://www.displaymyhostname.com/等站点检测到的主机名来找到外部IP地址。
为了说明我在说什么,这里有一个演示程序:
using System; using System.Net; using System.Linq; using System.Net.Sockets; using System.Collections.Generic; using System.Net.NetworkInformation; namespace LocalHostName { class Program { static void Main (string[] args) { var ipAddresses = Dns.GetHostAddresses ("www.google.com"); Socket socket; for (int i = 0; i < ipAddresses.Length; i++) { socket = new Socket (ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { socket.Connect (ipAddresses[i], 80); Console.WriteLine ("LocalEndPoint: {0}", socket.LocalEndPoint); break; } catch { socket.Dispose (); socket = null; if (i + 1 == ipAddresses.Length) throw; } } Console.ReadLine (); } } }
它打印出的任何IP地址都可能是SmtpClient在其HELO
/ EHLO
命令中使用的IP地址。
坏消息是System.Net.Mail.SmtpClient无法解决此问题。
好消息是,我节省了15%的汽车保险...嗯,我的意思是,我已经编写了自己的电子邮件库,名为MimeKit和MailKit,可以解决此问题。
还有一些好消息是,您可以轻松地将System.Net.Mail.MailMessage对象转换为MimeKit.MimeMessage对象(尽管显然,最好完全切换到MimeKit和MailKit)。
var mimeMessage = (MimeMessage) mailMessage;
这是使用MimeKit和MailKit重新编写的SMTPMailHelper类的样子:
using System; using MimeKit; using MailKit.Net.Smtp; public class SMTPMailHelper { const string SMTPServer = "mail.mydomain.com"; const string SMTPUserId = "myemail@mydomain.com"; const string SMTPPassword = "MyPasswordHidden"; const int SMTPPort = 25; public static void SendMail(string sendFrom, string sendTo, string subject, string body) { MimeMessage message = new MimeMessage (); TextPart text; message.From.Add (new MailboxAddress ("", sendFrom)); message.To.Add (new MailboxAdress ("", sendTo)); message.Subject = subject; if (body.ToLower ().Contains ("<html>")) text = new TextPart ("html") { Text = text }; else text = new TextPart ("plain") { Text = text }; message.Body = text; using (var smtp = new SmtpClient ()) { // use the IP address gotten from http://www.whatismyip.com/ // or the hostname gotten from http://www.displaymyhostname.com/ smtp.LocalDomain = "c-24-71-150-91.hsd1.ga.comcast.net"; smtp.Connect (SMTPServer, SMTPPort, false); smtp.Authenticate (SMTPUserId, SMTPPassword); smtp.Send (message); smtp.Disconnect (true); } } }
重要的是将SmtpClient的LocalDomain属性设置为的字符串。