• MailKit发送邮件


    背景

    由于smtpClient发送邮件偶发出现超时的情况,而且4.7版本后被标志为已过时,故换成MailKit方式。
    https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=netframework-4.7.1

    MailKit源码地址:https://github.com/jstedfast/MailKit

    实现

    示例demo地址:MailKitDemo

    1、引包

    创建MailKitDemo项目,安装nuget包,示例版本是3.1.1

    2、MailHelper

    封装MailHelper方法类,提供连接、授权、日志等操作。

    public static class MailHelper
    {
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="mailBodyEntity">邮件基础信息</param>
        /// <param name="sendServerConfiguration">发件人基础信息</param>
        public static SendResultEntity SendMail(MailBodyEntity mailBodyEntity,
            SendServerConfigurationEntity sendServerConfiguration)
        {
            if (mailBodyEntity == null)
            {
                throw new ArgumentNullException();
            }
    
            if (sendServerConfiguration == null)
            {
                throw new ArgumentNullException();
            }
    
            var sendResultEntity = new SendResultEntity();
    
            using (var client = new SmtpClient(new ProtocolLogger(MailMessage.CreateMailLog())))
            {
                client.ServerCertificateValidationCallback = (s, c, h, e) => true;
    
                Connection(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);
    
                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }
    
                SmtpClientBaseMessage(client);
    
                // Note: since we don't have an OAuth2 token, disable
                // the XOAUTH2 authentication mechanism.
                client.AuthenticationMechanisms.Remove("XOAUTH2");
    
                Authenticate(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);
    
                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }
    
                Send(mailBodyEntity, sendServerConfiguration, client, sendResultEntity);
    
                if (sendResultEntity.ResultStatus == false)
                {
                    return sendResultEntity;
                }
                client.Disconnect(true);
            }
            return sendResultEntity;
        }
    
    
        /// <summary>
        /// 连接服务器
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        private static void Connection(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Connect(sendServerConfiguration.SmtpHost, sendServerConfiguration.SmtpPort);
            }
            catch (SmtpCommandException ex)
            {
                sendResultEntity.ResultInformation = $"尝试连接时出错:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"尝试连接时的协议错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"服务器连接错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
        }
    
        /// <summary>
        /// 账户认证
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        private static void Authenticate(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Authenticate(sendServerConfiguration.SenderAccount, sendServerConfiguration.SenderPassword);
            }
            catch (AuthenticationException ex)
            {
                sendResultEntity.ResultInformation = $"无效的用户名或密码:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpCommandException ex)
            {
                sendResultEntity.ResultInformation = $"尝试验证错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"尝试验证时的协议错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"账户认证错误:{0}" + ex.Message;
                sendResultEntity.ResultStatus = false;
            }
        }
    
        /// <summary>
        /// 发送邮件
        /// </summary>
        /// <param name="mailBodyEntity">邮件内容</param>
        /// <param name="sendServerConfiguration">发送配置</param>
        /// <param name="client">客户端对象</param>
        /// <param name="sendResultEntity">发送结果</param>
        private static void Send(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration,
            SmtpClient client, SendResultEntity sendResultEntity)
        {
            try
            {
                client.Send(MailMessage.AssemblyMailMessage(mailBodyEntity));
            }
            catch (SmtpCommandException ex)
            {
                switch (ex.ErrorCode)
                {
                    case SmtpErrorCode.RecipientNotAccepted:
                        sendResultEntity.ResultInformation = $"收件人未被接受:{ex.Message}";
                        break;
                    case SmtpErrorCode.SenderNotAccepted:
                        sendResultEntity.ResultInformation = $"发件人未被接受:{ex.Message}";
                        break;
                    case SmtpErrorCode.MessageNotAccepted:
                        sendResultEntity.ResultInformation = $"消息未被接受:{ex.Message}";
                        break;
                }
                sendResultEntity.ResultStatus = false;
            }
            catch (SmtpProtocolException ex)
            {
                sendResultEntity.ResultInformation = $"发送消息时的协议错误:{ex.Message}";
                sendResultEntity.ResultStatus = false;
            }
            catch (Exception ex)
            {
                sendResultEntity.ResultInformation = $"邮件接收失败:{ex.Message}";
                sendResultEntity.ResultStatus = false;
            }
        }
    
        /// <summary>
        /// 获取SMTP基础信息
        /// </summary>
        /// <param name="client">客户端对象</param>
        /// <returns></returns>
        private static MailServerInformation SmtpClientBaseMessage(SmtpClient client)
        {
            var mailServerInformation = new MailServerInformation
            {
                Authentication = client.Capabilities.HasFlag(SmtpCapabilities.Authentication),
                BinaryMime = client.Capabilities.HasFlag(SmtpCapabilities.BinaryMime),
                Dsn = client.Capabilities.HasFlag(SmtpCapabilities.Dsn),
                EightBitMime = client.Capabilities.HasFlag(SmtpCapabilities.EightBitMime),
                Size = client.MaxSize
            };
    
            return mailServerInformation;
        }
    }
    

    主程序调用

    static void Main(string[] args)
    {
        
        var mailServerConfig = new SendServerConfigurationEntity()
        {
            SmtpPort = 0,                           //SMTP端口
            IsSsl = true,                           //启用Ssl
            SenderAccount = "****@qq.com",     //发件人
            SmtpHost = "smtp.qq.com",               //邮件Smtp服务,QQ:smtp.qq.com
            SenderPassword = "****",    //邮箱授权码
        };
        
        var mailBodyEntity = new MailBodyEntity()
        {
            Subject = "标题",
            Body = "邮件内容:<BR>百度:<a href='http://www.baidu.com'>点我</a>",
            Recipients = new List<string>() { "***@163.com"},      //收件人
            SenderAddress = "****@qq.com",     //发件人
        };
        var result = MailHelper.SendMail(mailBodyEntity, mailServerConfig);
        
    }
    

    配置项UI如下:

    3、效果及日志

    日志:

    邮件服务配置

    1、网易个人/VIP邮箱

    开启SMTP服务

    该授权码对应 EmailRequest中的Password
    网易个人邮箱/VIP邮箱的smtp地址:smtp.163.com
    网易个人邮箱/VIP邮箱的smtp端口: 465

    2、网易企业邮箱

    网易企业邮箱不需要生成授权码,Password使用邮箱的登录密码即可
    网易企业邮箱的smtp:smtp.ym.163.com
    网易企业邮箱的smtp端口号:465
    注意:网易企业邮箱的smtp不一定是smtp.ym.163.com,可以参考:https://qiye.163.com/help/client-profile.html

    3、outlook个人邮箱

    outlook个人邮箱smtp服务器是:smtp-mail.outlook.com
    outlook个人邮箱smtp端口号是:587
    Password是登录outlook邮箱的密码

    4、QQ个人邮箱

    QQ个人邮箱的流程类似网易个人邮箱,都需要生成授权码

    QQ个人邮箱的smtp地址是:smtp.qq.com
    QQ个人邮箱的smtp端口号是:465
    QQ个人邮箱的Password是上面的申请的授权码

  • 相关阅读:
    Linux内核同步
    Linux内核同步
    Linux内核同步
    Linux内核同步
    Linux内核同步
    Linux中断
    Linux中断
    Linux中断
    Linux中断
    Linux中断
  • 原文地址:https://www.cnblogs.com/liaoshiqi/p/16125311.html
Copyright © 2020-2023  润新知