个人博客-发送邮件优化

前言

之前的发送邮件就弄了个方法,比如回复评论会给评论的人发送邮件,留言回复也是,而且2者的代码有很多一样的地方,比较冗余。然后也是抽空优化一下,思路也是比较常用的工厂+策略模式,然后评论回复和留言回复的模板是不一样的,所以需要创建模板类和方法。。。

内容比较多,可以自己创建个小项目试试~

模板创建

⌨先把模板给定义好

定义EmailContent

主要是用传入发送邮件的内容,Content参数为必须,其他的可以根据自己的需求进行更改。

public class EmailContent
{
public string Content { get; set; }
public string? Link { get; set; }
} public class EmailContent<T>
{
public string Content { get; set; }
public string Link { get; set; }
public T Data { get; set; }
}

首先创建一个基类定义邮件内容生成的方法:

  • EmailTemplate:基本模板类
  • SEmailTemplate:泛型模板类
public abstract class EmailTemplateBase
{
protected abstract string GetStyle();
} public abstract class EmailTemplate:EmailTemplateBase
{
public string GenerateContent(EmailContent emailContent)
{
return $"<html>\n<head>\n<style>{GetStyle()}</style>\n</head>\n<body>\n{GetBodyContent(emailContent)}\n</body>\n</html>";
}
protected abstract string GetBodyContent(EmailContent emailContent);
} public abstract class SEmailTemplate<T>:EmailTemplateBase
{
public string GenerateContent(EmailContent<T> emailContent)
{
return $"<html>\n<head>\n{GetStyle()}\n</head>\n<body>\n{GetBodyContent(emailContent)}\n</body>\n</html>";
} protected abstract string GetBodyContent(EmailContent<T> emailContent);
}

然后为每一种邮件内容创建一个子类:

情况一:简单情况

只发送简单的邮件内容,不包含对象等复杂内容。

  • GetStyle 里面写样式就行
  • GetBodyContent 里面写内容
public class MessageBoardNotificationEmailTemplate:EmailTemplate
{
protected override string GetStyle()
{
return @"
/* 添加样式 */
body {
font-family: Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
color: #333;
}
.box {
background-color:#90F8FF ;
border-radius: 5px;
padding: 20px;
}
h1 {
font-size: 24px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
p {
margin-bottom: 10px;
color: #333;
}
a {
color: #333;
}";
} protected override string GetBodyContent(EmailContent emailContent)
{
return $@"
<div class='box'>
<h1>ZY知识库</h1>
<h3>留言板通知</h3>
<p>内容如下:{emailContent.Content}</p>
<p>点击跳转:<a href='https://pljzy.top/MsgBoard?page=1'>留言板地址</a></p>
</div>";
}
}

情况二:复杂情况

  • GetStyle 同上
  • GetBodyContent 里面参数为泛型参数EmailContent<LinkExchange>,这样在发送邮件时就能发送对象信息
public class LinksNotificationEmailTemplate:SEmailTemplate<LinkExchange>
{
protected override string GetStyle()
{
return "";
} protected override string GetBodyContent(EmailContent<LinkExchange> emailContent)
{
const string blogLink = "<a href=\"https://pljzy.top\">ZY知识库</a>";
var sb = new StringBuilder();
sb.AppendLine($"<p>{emailContent.Content}</p>");
sb.AppendLine($"<br>");
sb.AppendLine($"<p>以下是您申请的友链信息:</p>");
sb.AppendLine($"<p>网站名称:{emailContent.Data.Name}</p>");
sb.AppendLine($"<p>介绍:{emailContent.Data.Description}</p>");
sb.AppendLine($"<p>网址:{emailContent.Data.Url}</p>");
sb.AppendLine($"<p>站长:{emailContent.Data.WebMaster}</p>");
sb.AppendLine($"<p>补充信息:{emailContent.Data.Reason}</p>");
sb.AppendLine($"<br>");
sb.AppendLine($"<br>");
sb.AppendLine($"<br>");
sb.AppendLine($"<p>本消息由 {blogLink} 自动发送,无需回复。</p>");
return sb.ToString();
}
}

发送邮件服务

首先,创建一个接口定义邮件发送服务

public interface IEmailService
{
Task SendEmail(string recipient, EmailTemplate template, EmailContent emailContent);
Task SendEmail<T>(string recipient, SEmailTemplate<T> template, EmailContent<T> emailContent);
}

然后创建实现类MimeKitEmailService ,这里用的是​MimeKit库生成邮件内容

public class MimeKitEmailService : IEmailService
{
private readonly SmtpClient client; public MimeKitEmailService(SmtpClient client)
{
this.client = client;
} public async Task SendEmail(string recipient, EmailTemplate template, EmailContent emailContent)
{
var message = CreateEmailMessage(recipient, template.GenerateContent(emailContent));
await SendAsync(message);
} public async Task SendEmail<T>(string recipient, SEmailTemplate<T> template, EmailContent<T> emailContent)
{
var message = CreateEmailMessage(recipient, template.GenerateContent(emailContent));
await SendAsync(message);
} private MimeMessage CreateEmailMessage(string recipient, string content)
{
var message = new MimeMessage();
message.From.Add(new MailboxAddress("ZY", "zy1767992919@163.com"));
message.To.Add(new MailboxAddress("", recipient));
message.Subject = "来自ZY知识库通知~";
message.Body = new TextPart("html")
{
Text = content
}; return message;
} private async Task SendAsync(MimeMessage message)
{
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
}

创建工厂类

配置

将邮箱信息存放在appsettings.json文件中方便统一管理

{
"Email": {
"Address": "你的邮箱",
"Password": "授权码"
}
}

然后创建一个类对应上述参数

public class EmailConfig
{
public string Address { get; set; }
public string Password { get; set; }
}

Program.cs文件中绑定EmailConfig类,添加到容器中

builder.Services.Configure<EmailConfig>(builder.Configuration.GetSection("Email"));

工厂类

创建EmailServiceFactory工厂类用于实例化EmailService

  1. 网易:smtp.163.com
  2. QQ:smtp.qq.com

EmailServiceFactory类中注入IOptions<EmailConfig>来邮箱信息配置

public class EmailServiceFactory
{
private readonly EmailConfig emailConfig;
public EmailServiceFactory(IOptions<EmailConfig> emailConfigOptions)
{
emailConfig = emailConfigOptions.Value;
}
public async Task<IEmailService> CreateEmailService()
{
var client = new SmtpClient();
// configure the client
await client.ConnectAsync("smtp.163.com", 465, true);
await client.AuthenticateAsync(emailConfig.Address, emailConfig.Password); return new MimeKitEmailService(client);
}
}

注册EmailServiceFactory服务

builder.Services.AddTransient<EmailServiceFactory>();

发送邮件

声明 IEmailServiceEmailServiceFactory变量,然后使用 emailServiceFactoryCreateEmailService 方法异步创建一个 IEmailService 对象用于创建邮箱通信,并将其赋给 emailService 变量,然后new一个模板对象,最后调用emailServiceSendEmail方法发送邮件

private IEmailService emailService;
private readonly EmailServiceFactory _emailServiceFactory; public LinkExchangeService(MyDbContext myDbContext,
EmailServiceFactory emailServiceFactory)
{
_myDbContext = myDbContext;
_emailServiceFactory = emailServiceFactory;
} public async Task SendEmailOnAdd(LinkExchange item)
{
//创建邮箱连接
emailService = await _emailServiceFactory.CreateEmailService();
//内容模板
var template = new LinksNotificationEmailTemplate();
//发送邮件
await emailService.SendEmail(item.Email, template,
new EmailContent<LinkExchange>()
{
Content = "您好,友链申请已通过!感谢支持,欢迎互访哦~",
Data = item
});
}

参考资料

.NET 个人博客-发送邮件优化🧐的更多相关文章

  1. Hexo博客主题优化

    Hexo博客主题优化 添加背景图 在 themes/*/source/css/_custom/custom.styl 中添加如下代码: body{ background:url(/images/bg. ...

  2. 最近忙科研立项 & 对博客的优化

    最近一直在忙科研立项.... 立项书 & 答辩 ... 接下来,将对博客进行优化... (1) 依据书来学习的[需要大量截图],将用微软的 OneNote 写笔记,然后打包成pdf,上传到我的 ...

  3. hexo博客的优化与配置——加入统计代码

    今天看着csdn博客的訪客数,就想给hexo博客也加入统计訪客的插件,上次折腾了个pacman主题,中间自带的是goole的统计,easy被墙,所以就想换一个统计工具,看了好多人用的都是cnzz的站长 ...

  4. Android 查阅博客1_app优化_1大小

    Android  App  Bundle (google play 商店发布应用的话,可自行深入了解下,这里不做介绍) http://mp.weixin.qq.com/s?__biz=MzAwODY4 ...

  5. [软软软]技术博客-Commitizen优化git commit

    工具介绍 commitizen/cz-cli是一个规范git commit的工具,使用它代替git commit能够方便有效地写好提交的log,使得团队项目的版本信息更清晰. 安装 (全局安装) np ...

  6. 如何搭建一个独立博客——简明Github Pages与Hexo教程

    摘要:这是一篇很详尽的独立博客搭建教程,里面介绍了域名注册.DNS设置.github和Hexo设置等过程,这是我写得最长的一篇教程.我想将我搭建独立博客的过程在一篇文章中尽可能详细地写出来,希望能给后 ...

  7. 使用 github Pages 服务建立个人独立博客全过程

    你是否有这样子的需求,只是想简单的写写文章,记录下自己的学习心得.成长经历等,都是些文字内容,不需要配置使用数据库.不想购买服务器自己搭建站点,只是想安安静静的用比较舒服的方式来写篇文章. 静态博客就 ...

  8. 如何用hexo+github搭建个人博客

    搭建环境 1.安装 Node.js: https://nodejs.org/en/ windows下点击链接,下载安装即可;Linux下更加简单,在终端下输入sudo apt-get install ...

  9. hexo+github搭建博客(超级详细版,精细入微)

    # 前言 你了解[Hexo]( https://hexo.io/zh-cn/ "Hexo官网")吗? Hexo是一个静态博客框架,基于Node.js,将Markdown文章通过渲染 ...

  10. Hexo+github如何搭建博客

    前言 博客有第三方平台,也可以自建,比较早的有博客园.CSDN,近几年新兴的也比较多诸如:WordPress.segmentFault.简书.掘金.知乎专栏.Github Page 等等. 这次我要说 ...

随机推荐

  1. 如何查看Navicat已有连接的密码(简单清晰)

    1.打开Navicat,File > Export Connections 2.选择你想查看的数据库,并勾选下方的 [导出密码],导出 3.去文件里找到Password 4.打开网址 https ...

  2. 跟羽夏学 Ghidra ——简述

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...

  3. 深入剖析:如何使用Pulsar和Arthas高效排查消息队列延迟问题

    背景 前两天收到业务反馈有一个 topic 的分区消息堆积了: 根据之前的经验来看,要么是业务消费逻辑出现问题导致消费过慢,当然也有小概率是消息队列的 Bug(我们使用的是 pulsar). 排查 通 ...

  4. SQL Server实战五:存储过程与触发器

      本文介绍基于Microsoft SQL Server软件,实现数据库存储过程与触发器的创建.执行.修改与删除等操作. 目录 1 交互式创建并执行--存储过程一 2 交互式创建并执行--存储过程二 ...

  5. OpenCV计算机视觉入门之图像色彩空间转换

    目录 1. 引言 2. 概念 2.1 数字图像 2.2 色彩空间 3. 实践-图像读取 5. 完整代码 6. 总结 1. 引言 本文通过导入函数库.读取图像.转换图像色彩空间.缩放图像和保存图像五个步 ...

  6. WEB服务与NGINX(13)-NGINX的日志功能

    1.nginx的日志功能 定义nginx的访问日志显示的格式,即具体记录的客户端信息和格式.日志功能由ngx_http_log_module模块提供. log_format name string . ...

  7. fastposter v2.8.3 发布 电商海报生成器

    fastposter v2.8.3 发布 电商海报生成器 fastposter海报生成器,电商海报编辑器,电商海报设计器,fast快速生成海报 海报制作 海报开发.贰维海报,图片海报,分享海报贰维码推 ...

  8. console小知识

    console.log(JSON.stringify(object,null,2));

  9. 记一次ThreadLocal中的用户信息混乱问题

    前言 记录一次开发中遇到的关于 ThreadLocal 问题,场景是数据库表中的操作人总是无缘无故的被更改,排查了几遍代码才发现是 ThreadLocal 没有及时清理导致的. 一.为什么使用 Thr ...

  10. 网络拓扑—WEB-IIS服务搭建

    目录 WEB-IIS服务搭建 网络拓扑 配置网络 IIS PC 安装IIS服务 配置IIS服务(默认站点) PC机访问网页 配置IIS服务(新建站点) PC机访问网页 WEB-IIS服务搭建 网络拓扑 ...