错误: 信箱不可用。服务器响应为:拒绝访问 - 无效的HELO名称(请参阅RFC2821 4.1.1.1)
描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。
异常详细信息:System.Net.Mail.SmtpException:邮箱不可用。服务器响应为:拒绝访问 - 无效的HELO名称(请参阅RFC2821 4.1.1.1)
来源错误第61行:
Line 59:
Line 60: SmtpClient smtp = new SmtpClient(SMTPServer, SMTPPort);
Line 61: smtp.Credentials = new NetworkCredential(SMTPUserId, SMTPPassword);
Line 62: smtp.Send(mail);
Line 63: }
源文件:\ Websites \ Client \ Reports \ ContactUs.aspx.cs行:61
=============================================== ==========================
我的源代码:
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
string name = txtFirstName.Text + " " + txtLastName.Text;
string clientID = Session["CustomerID"].ToString();
string message = txtMessage.Text;
string email = txtEmail.Text;
string company = txtCompany.Text;
string phone = txtPhone.Text;
SMTPMailHelper.SendMail(email, "myemail@domain.com", "Contact from Client: " + clientID + ": " + name + " " + company, message);
}
我放弃了一些与条件声明相关的脚本。 而这就是它的余生:
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)
{
MailAddress fromAddress = new MailAddress(sendFrom);
MailAddress toAddress = new MailAddress(sendTo);
MailMessage mail = new MailMessage();
mail.From = fromAddress;
mail.To.Add(toAddress);
mail.Subject = subject;
if (body.ToLower().Contains("<html>"))
{
mail.IsBodyHtml = true;
}
mail.Body = body;
SmtpClient smtp = new SmtpClient(SMTPServer, SMTPPort);
smtp.Credentials = new NetworkCredential(SMTPUserId, SMTPPassword);
smtp.Send(mail);
}
}
答案 0 :(得分:4)
您遇到的问题是SmtpClient正在发出HELO
或EHLO
命令,其中包含您的服务器SMTP拒绝的主机名/域字符串。
我显然无法知道微软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
命令中使用的地址。
坏消息是,无法使用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属性设置为的字符串。