asp.net core 发送QQ邮件

时间:2024-02-25 20:06:54

.netframework 中发送邮件的api主要是使用SmtpClient 类,到了.netcore,官方并不推荐使用SmtpClient API,详情可查看官方说明:https://docs.microsoft.com/en-us/dotnet/api/system.net.mail.smtpclient?view=net-5.0,因此这里我使用第三方邮件发送库:MailKit 来进行邮件的发送。

配置QQ邮箱

  • 登录QQ邮箱,选择设置->账户->POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务

    开启POP3/SMTP服务以及IMAP/SMTP服务。

POP3服务开启流程
1.开启POP3服务![]
(https://www.lovecoding.com.cn:99//5596824483738550145.png)

2.POP3服务开启成功后如下图所示,会弹出一个框,注意:不是用这个框里的密码进行发送邮件

3.生成用于发送邮件的授权码

IMAP服务开启流程
开启流程和POP3开启流程类似。

创建邮件发送接口

  • 安装nuget包MailKit
  • 添加IMailService接口
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace CommonLib.Email
    {
    	public interface IMailService
    	{
    		Task SendEmailAsync(MailRequest mailRequest);
    	}
    }
    
  • 创建邮件信息相关实体类
    using Microsoft.AspNetCore.Http;
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace CommonLib.Email
    {
    	public class MailRequest
    	{
    		//收件地址
    		public string ToEmail { get; set; }
    		//邮件标题
    		public string Subject { get; set; }
    		//邮件内容,支持html
    		public string Body { get; set; }
    		//要发送的附件
    		public List<IFormFile> Attachments { get; set; }
    	}
    }
    
  • 创建邮箱配置信息实体类
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace CommonLib.Email
    {
    	public class MailSettings
    	{
    		//用于发送邮件的邮箱账号
    		public string Mail { get; set; }
    		//显示名称
    		public string DisplayName { get; set; }
    		//用于发送邮件的邮箱账号的授权码
    		public string Password { get; set; }
    		//用于发送邮件的邮箱服务器,QQ邮箱是:smtp.qq.com
    		public string Host { get; set; }
    		//用于发送邮件的邮箱服务器端口,QQ邮箱的端口是25
    		public int Port { get; set; }
    	}
    }
    
  • 创建实现具体邮件发送逻辑的类,并实现IMailService接口
    using MailKit.Net.Smtp;
    using MailKit.Security;
    using Microsoft.Extensions.Options;
    using MimeKit;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    namespace CommonLib.Email
    {
    	public class MailService : IMailService
    	{
    		private readonly MailSettings _mailSettings;
    		public MailService(IOptions<MailSettings> mailSettings)
    		{
    			_mailSettings = mailSettings.Value;
    			//这里这个密码是QQ邮箱授权码
    			_mailSettings.Password = mailSettings.Value.Password;
    		}
    		public async Task SendEmailAsync(MailRequest mailRequest)
    		{
    			var email = new MimeMessage();
    			//一定要使用下面这句代码添加发送人邮箱信息,否则QQ收件箱那边无法看到发送人的邮箱信息。
    			email.From.Add(MailboxAddress.Parse(_mailSettings.Mail));
    			email.Sender = MailboxAddress.Parse(_mailSettings.Mail);
    			email.To.Add(MailboxAddress.Parse(mailRequest.ToEmail));
    			email.Subject = mailRequest.Subject;
    			var builder = new BodyBuilder();
    			if (mailRequest.Attachments != null)
    			{
    				byte[] fileBytes;
    				foreach (var file in mailRequest.Attachments)
    				{
    					if (file.Length > 0)
    					{
    						using (var ms = new MemoryStream())
    						{
    							file.CopyTo(ms);
    							fileBytes = ms.ToArray();
    						}
    						builder.Attachments.Add(file.FileName, fileBytes, MimeKit.ContentType.Parse(file.ContentType));
    					}
    				}
    			}
    			builder.HtmlBody = mailRequest.Body;
    			email.Body = builder.ToMessageBody();
    			using (var smtp = new SmtpClient())
    			{
    				smtp.Connect(_mailSettings.Host, _mailSettings.Port, SecureSocketOptions.StartTls);
    				smtp.Authenticate(_mailSettings.Mail, _mailSettings.Password);
    				await smtp.SendAsync(email);
    				smtp.Disconnect(true);
    			}
    		}
    	}
    }
    

打开appsettings.Development.json文件,加入发送邮件所用到的邮箱账号、邮箱服务器等信息。

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "MailSettings": {
    "Mail": "2782815239@qq.com",
    "DisplayName": "陈新",
    "Password": "xxx",
    "Host": "smtp.qq.com",
    "Port": 25
  },
  "urls": "http://*:80"
}

到这里,基本配置工作已经完成,但是需要注意的是将代码发布到云服务器上(如腾讯云)时需要注意解封25端口,否则无法正常发送邮件。

腾讯云25端口开放方法请参见:https://cloud.tencent.com/document/product/213/40436