邮件服务是一般的系统都会拥有和需要的功能,但是对于.NET项目来说,邮件服务的创建和使用会较为的麻烦。.NET对于邮件功能提供了System.Net.Mail用于创建邮件服务,该基础服务提供邮件的基础操作,并且使用也较为的简单。对于真正将该功能使用于项目的人,就会慢慢发现其中的优缺点,甚至有些时候不能忍受其中的问题。在这里介绍一种微软用于替代System.Net.Mail的邮件服务组件MailKit和MimeKit,官网地址:。GitHub地址:https://github.com/jstedfast/MimeKit。下面就具体的介绍一下。
一.MailKit和MimeKit基础概述:MailKit组件的支持的客户端类型比较多,例如SMTP客户端、POP3客户端、IMAP4客户端。该组件是一个跨平台的Email组件,该组件支持.NET 4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone 8.1等等平台。
MimeKit提供了一个MIME解析器,组件具备的解析特性灵活、性能高、很好的处理各种各样的破碎的MIME格式化。MimeKit的性能实际上与GMime相当。
该组件在安全性的还是比较高的,处理安全的方式较多,SASL认证、支持S / MIME v3.2、支持OpenPGP、支持DKIM签名等等方式。Mailkit组件可以通过CancellationToken取消对应的操作,CancellationToken传播应取消操作的通知,一个的CancellationToken使线程,线程池工作项目之间,或取消合作任务的对象。过实例化CancellationTokenSource对象来创建取消令牌,该对象管理从其CancellationTokenSource.Token属性检索的取消令牌。然后,将取消令牌传递到应该收到取消通知的任意数量的线程,任务或操作。令牌不能用于启动取消。
MailKit组件支持异步操作,在内部编写的有关I/O异步操作的类。
二.创建基础邮件服务:介绍过MailKit和MimeKit组建的基础信息,接下来就介绍一下如何使用两个组件的基本功能,在这里我将基本操作做了一个简单的封装,一般的项目可以直接引用封装好的类,大家可以根据实际的情况对该组件进行扩展。
1.邮件发送基础服务API/// <summary> /// 邮件服务API /// </summary> public static class MailServiceApi { /// <summary> /// 发送邮件 /// </summary> /// <param>邮件基础信息</param> /// <param>发件人基础信息</param> public static SendResultEntity SendMail(MailBodyEntity mailBodyEntity, SendServerConfigurationEntity sendServerConfiguration) { if (sendServerConfiguration == null) { throw new ArgumentNullException(); } if (sendServerConfiguration == null) { throw new ArgumentNullException(); } var sendResultEntity = new SendResultEntity(); using (var client = new SmtpClient(new ProtocolLogger(CreateMailLog()))) { client.ServerCertificateValidationCallback = (s, c, h, e) => true; Connection(mailBodyEntity, sendServerConfiguration, client, sendResultEntity); if (sendResultEntity.ResultStatus == false) { return sendResultEntity; } SmtpClientBaseMessage(client); 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>邮件内容</param> /// <param>发送配置</param> /// <param>客户端对象</param> /// <param>发送结果</param> public 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>邮件内容</param> /// <param>发送配置</param> /// <param>客户端对象</param> /// <param>发送结果</param> public 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>邮件内容</param> /// <param>发送配置</param> /// <param>客户端对象</param> /// <param>发送结果</param> public 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>客户端对象</param> /// <returns></returns> public 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; } /// <summary> /// 创建邮件日志文件 /// </summary> /// <returns></returns> public static string CreateMailLog() { var logPath = AppDomain.CurrentDomain.BaseDirectory + "/DocumentLog/" + Guid.NewGuid() + ".txt"; if (File.Exists(logPath)) return logPath; var fs = File.Create(logPath); fs.Close(); return logPath; } }