.Net SMTP 邮件发送 问题发生与解决

闲来无事想给公司的项目中的邮件功能完善一下。

网上邮件发送的代码一箩筐,这边我也列了一下

在此之前需要开通邮件的SMTP功能

在这里插入图片描述
在这里插入图片描述
这边需要尤其注意一点,代码里面的密码部分必须使用这个授权码登入。
其他邮箱大致一样

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="account">配置</param>
        /// <param name="mailModel">信息</param>
        public static void Send(MailAccount account, MailModel mailModel)
        {
            try
            {
                MailMessage mailMessage = new MailMessage();
                mailMessage.From = new MailAddress(account.Account, account.AccountName);
                //发件人
                if (!string.IsNullOrEmpty(mailModel.To) && (mailModel.To).IndexOf("@") > 0)
                {
                    var ToArray = mailModel.To.Split(',');
                    foreach (var item in ToArray)
                    {
                        mailMessage.To.Add(new MailAddress(item));
                    }
                }
                //抄送人
                if (!string.IsNullOrEmpty(mailModel.CC) && (mailModel.CC).IndexOf("@") > 0)
                {
                    var CCArray = mailModel.CC.Split(',');
                    foreach (var item in CCArray)
                    {
                        mailMessage.CC.Add(new MailAddress(item));
                    }
                }
                //密送人
                if (!string.IsNullOrEmpty(mailModel.Bcc) && (mailModel.Bcc).IndexOf("@") > 0)
                {
                    var BccArray = mailModel.Bcc.Split(',');
                    foreach (var item in BccArray)
                    {
                        mailMessage.Bcc.Add(new MailAddress(item));
                    }
                }
                //附件
                var filePath = DirFileHelper.GetAbsolutePath("~/Source/EmailFile/");
                foreach (MailFile item in mailModel.Attachment)
                {
                    var attachment = new Attachment(filePath + item.FileId);
                    attachment.Name = item.FileName;
                    mailMessage.Attachments.Add(attachment);
                }
                mailMessage.Subject = mailModel.Subject;
                mailMessage.Body = mailModel.BodyText;
                mailMessage.IsBodyHtml = true;
                mailMessage.Priority = MailPriority.Normal;
                mailMessage.SubjectEncoding = Encoding.UTF8;
                mailMessage.BodyEncoding = Encoding.UTF8;
                //不被当作垃圾邮件的关键代码--Begin            
                mailMessage.Headers.Add("X-Priority", "3");
                mailMessage.Headers.Add("X-MSMail-Priority", "Normal");
                mailMessage.Headers.Add("X-Mailer", "Microsoft Outlook Express 6.00.2900.2869");
                mailMessage.Headers.Add("X-MimeOLE", "Produced By Microsoft MimeOLE V6.00.2900.2869");
                mailMessage.Headers.Add("ReturnReceipt", "1");
                //不被当作垃圾邮件的关键代码--End        
                using (SmtpClient smtpClient = new SmtpClient(account.SMTPHost, account.SMTPPort))
                {
                    smtpClient.UseDefaultCredentials = false;
                    smtpClient.Credentials = new NetworkCredential(account.Account, account.Password);
                    smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                    smtpClient.Send(mailMessage);
                }
                mailMessage.Subject = mailModel.Subject;
                mailMessage.Body = mailModel.BodyText;
                设置邮件的格式
                mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
                mailMessage.IsBodyHtml = true;
                //设置邮件的发送级别
                mailMessage.Priority = MailPriority.Normal;
                SmtpClient client = new SmtpClient();
                //设置用于 SMTP 事务的主机的名称,填IP地址也可以了
                client.Host = account.SMTPHost;
                //设置用于 SMTP 事务的端口,默认的是 25
                client.Port = account.SMTPPort;
                client.UseDefaultCredentials = false;
                //邮箱登陆名和密码
                client.Credentials = new System.Net.NetworkCredential(account.Account, account.Password);
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                client.Send(account.Account, mailMessage.To.ToString(), mailMessage.Subject, mailMessage.Body);
                mailMessage.Subject = "你好标题";
                //设置邮件的内容
                mailMessage.Body = "内容你好";
                //设置邮件的格式
                mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
                mailMessage.IsBodyHtml = true;
                //设置邮件的发送级别
                mailMessage.Priority = MailPriority.Normal;
                SmtpClient client = new SmtpClient();
                //设置用于 SMTP 事务的主机的名称,填IP地址也可以了
                client.Host = "smtp.163.com";
                //设置用于 SMTP 事务的端口,默认的是 25
                client.Port = 25;
                client.UseDefaultCredentials = false;
                //邮箱登陆名和密码
                client.Credentials = new System.Net.NetworkCredential("xxxx@163.com", "xxxxxx密码");
                client.DeliveryMethod = SmtpDeliveryMethod.Network;
                try
                {
                    client.Send("xxxx@163.com", "xxxx@qq.com", "你好标题", "内容你好");
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

测试没有问题,其实代码很简单。

接下来才是坑的开始,最主要的坑还是163邮箱。

把程序架设到服务器上运行,很奇怪不能发送邮件了。
首先想到了防火墙,也将25端口开放了,还是不行,谷歌一下资料,发现问题所在。
在这里插入图片描述
因为安全原因关闭了25端口,好吧,那就使用ssl登入吧,把端口换成了465。

本地测试,不通过,发不了邮件。

报错信息如下:
SmtpException:无法读取从传输连接数据:smtp 465 net_io_connectionclosed

???????????????????????????????????????
连接不上?代码也没更改,就换了端口加了EnableSsl

client.EnableSsl = true;//经过ssl加密  

陷入沉思。
继续谷歌,不得不说谷歌大法好,比宏彦祸水家的广告度好太多了。
微软的解释
https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient.enablessl?view=netframework-4.8
Remarks
The EnableSsl property specifies whether SSL is used to access the specified SMTP mail server.

The default value for this property can also be set in a machine or application configuration file. Any changes made to the EnableSsl property override the configuration file settings.

The SmtpClient class only supports the SMTP Service Extension for Secure SMTP over Transport Layer Security as defined in RFC 3207. In this mode, the SMTP session begins on an unencrypted channel, then a STARTTLS command is issued by the client to the server to switch to secure communication using SSL. See RFC 3207 published by the Internet Engineering Task Force (IETF) for more information.

An alternate connection method is where an SSL session is established up front before any protocol commands are sent. This connection method is sometimes called SMTP/SSL, SMTP over SSL, or SMTPS and by default uses port 465. This alternate connection method using SSL is not currently supported.

You can use ClientCertificates to specify which client certificates should be used to establish the SSL connection. The ServerCertificateValidationCallback allows you to reject the certificate provided by the SMTP server. The SecurityProtocol property allows you to specify the version of the SSL protocol to use.

意思就是.Net.Mail 不支持ssl,不支持!!!!!

继续谷歌,ssl目前 只有低版本的.Web.Mail才支持ssl,对微软这个骚操作不太理解,低版本支持,高版本不支持,怪不得。

上干货

// A code block
var foo = 'bar';
public static void SendEmailSSL(string subject, string body, string mailTo)
        {
            System.Web.Mail.MailMessage mmsg = new System.Web.Mail.MailMessage();
            //验证  
            mmsg.Subject = subject;// "zhuti1";//邮件主题

            mmsg.BodyFormat = MailFormat.Html;
            mmsg.Body = body;// "wqerwerwerwer";//邮件正文
            mmsg.BodyEncoding = Encoding.UTF8;//正文编码

            mmsg.Priority = System.Web.Mail.MailPriority.High;//优先级

            mmsg.From = "xxxxx@163.com";//发件者邮箱地址
            mmsg.To = mailTo;//收件人收箱地址
            StringBuilder mailCCString = new StringBuilder();

            //foreach (var cc in mailCC)
            //{
            //    mailCCString.Append(cc + ";");
            //}
            //mmsg.Cc = "474305148@qq.com";


            mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
            //登陆名  
            mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "xxxxx@163.com");
            //登陆密码  
            mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "xxxxxx密码");

            mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", 465);//端口 
            mmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true");
            System.Web.Mail.SmtpMail.SmtpServer = "smtp.163.com";    //企业账号用smtp.exmail.qq.com 

            SmtpMail.Send(mmsg);
        }

这下应该没问题了吧,然而事与愿违啊。

又报错。。。。。。。。。。
在这里插入图片描述
按照163官网上说的,说是垃圾邮件,不给发送,改了主题,改了内容,超级正规,然而还是这个错。

这个问题困扰了我大概1个小时,没法解决。

问了一下公司以前离职的一位大牛,他那边试了一下没问题,能发送,卧槽,什么骚操作 ,脸黑???????

难道是网的问题?

重启路由,电信是这样的,一般给的都不是固定IP都是片区的局域网,其实打10000可以申请到稍微固定的ip,就是跳出局域网 之外,虽然说一个月 左右会变一次ip地址或者重新拨号就会变,但是总比局域网的ip好,题外话,题外话,申请 这种 ip 只要打1000说你家要装监控,就完事了。

重启路由,ok,程序能跑了,可以发邮件。那为什么呢?

谷歌,对,还是 谷歌。

看到一些文件,论坛,有讲到,如果多次错误连接smtp服务器,运营商会封ip,判断你为发小广告了。好吧,原来如此。

本地可以,服务器不行,换台服务器,ok可行,当时也不知道第一台服务器是不是IP被封了,等两天再试试,过了两天试了一下,居然可以用了,完美 。原来也不是永久封啊。

总结一下

1.需要开通邮箱的smtp功能
2.登入第三方邮箱需要独立授权码
3.一般云服务器 25端口都是默认封禁的
4.System.Net.Mail 不支持ssl,老版本的System.Web.Mail 可以使用ssl加密
5.不要频繁报错调试,有几率会被封IP,具体时间不确定

再放一个简单的demo吧,直接可以用。

https://download.csdn.net/download/molu474305148/11578642

准备给个免费的,csdn改版不能自己设置积分。。。。无奈!!!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值