You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中如何发送带变量的自定义HTML邮件?

实现可复用的HTML邮件发送服务(带变量替换)

一、先重构EmailService,支持动态参数和HTML内容

首先把硬编码的内容改成可传入的参数,同时支持HTML邮件体和变量替换。修改后的代码示例:

public class EmailService : IEmailService
{
    // 建议从配置文件读取SMTP参数,这里简化示例
    private readonly string _smtpHost = "smtp.mailtrap.io";
    private readonly int _smtpPort = 2525;
    private readonly string _smtpUsername = "your-mailtrap-username";
    private readonly string _smtpPassword = "your-mailtrap-password";
    private readonly string _senderName = "你的应用名称";
    private readonly string _senderEmail = "no-reply@yourapp.com";

    // 通用发送方法,支持HTML模板和变量替换
    public void SendEmail(string toEmail, string subject, string htmlTemplate, Dictionary<string, string> variables = null)
    {
        var email = new MimeMessage();
        email.From.Add(new MailboxAddress(_senderName, _senderEmail));
        email.To.Add(MailboxAddress.Parse(toEmail));
        email.Subject = subject;

        // 替换模板中的变量
        var processedHtml = ReplaceTemplateVariables(htmlTemplate, variables);

        // 创建HTML邮件体,可选添加纯文本 fallback 兼容旧邮箱
        email.Body = new TextPart("html")
        {
            Text = processedHtml
        };

        using var smtp = new SmtpClient();
        smtp.Connect(_smtpHost, _smtpPort, SecureSocketOptions.StartTls);
        smtp.Authenticate(_smtpUsername, _smtpPassword);
        smtp.Send(email);
        smtp.Disconnect(true);
    }

    // 基础变量替换方法(适合简单场景)
    private string ReplaceTemplateVariables(string template, Dictionary<string, string> variables)
    {
        if (variables == null || variables.Count == 0)
            return template;

        foreach (var kvp in variables)
        {
            template = template.Replace($"{{{{{kvp.Key}}}}}", kvp.Value);
        }

        return template;
    }
}

二、模板与变量的处理方案

1. 数据库存储模板(对应你最初的想法)

把验证邮件、重置密码邮件等不同模板存在数据库中,模板里用{{变量名}}作为占位符,比如{{Username}}、{{VerificationLink}}。

示例数据库中存储的验证邮件模板:

<h1>欢迎加入{{AppName}}!</h1>
<p>亲爱的{{Username}},请点击下方链接验证你的邮箱:</p>
<a href="{{VerificationLink}}">验证邮箱</a>
<p>如果这不是你操作的,请忽略此邮件。</p>

发送时从数据库取出模板,传入变量字典调用通用方法:

// 假设你有仓储类负责读取数据库模板
var verificationTemplate = _emailTemplateRepo.GetTemplate("EmailVerification");

var variables = new Dictionary<string, string>
{
    {"Username", user.Username},
    {"AppName", "你的应用"},
    {"VerificationLink", $"https://yourapp.com/verify?token={user.VerificationToken}"}
};

_emailService.SendEmail(user.Email, "请验证你的邮箱", verificationTemplate, variables);

2. 使用轻量级模板引擎(复杂场景推荐)

如果模板需要循环、条件判断等逻辑,基础字符串替换不够用,可以用Scriban或RazorLight这类模板引擎。

以Scriban为例:

  • 先安装NuGet包:Install-Package Scriban
  • 修改模板渲染方法:
private string RenderScribanTemplate(string templateContent, Dictionary<string, object> variables)
{
    var template = Template.Parse(templateContent);
    return template.Render(variables, memberRenamer: null);
}
  • 支持逻辑的模板示例:
<h1>Hello {{username}}!</h1>
{{if is_new_user}}
<p>欢迎你成为我们的新用户!</p>
{{end}}
<p>你的重置密码链接:<a href="{{reset_link}}">点击重置</a></p>
  • 调用时传入变量:
var variables = new Dictionary<string, object>
{
    {"username", user.Username},
    {"is_new_user", true},
    {"reset_link", resetUrl}
};
var processedHtml = RenderScribanTemplate(resetTemplate, variables);
_emailService.SendEmail(user.Email, "重置你的密码", processedHtml);

3. 内嵌模板(简单场景快速实现)

如果邮件类型不多,也可以把模板作为静态字符串或资源文件存在代码里,比如创建一个静态类:

public static class EmailTemplates
{
    public const string PasswordReset = @"
        <h2>重置你的密码</h2>
        <p>亲爱的{{Username}},请点击下方链接重置你的密码:</p>
        <a href=""{{ResetLink}}"">重置密码</a>
        <p>链接24小时内有效。</p>
    ";

    public const string EmailVerification = @"
        <h2>验证你的邮箱</h2>
        <p>亲爱的{{Username}},请点击下方链接完成邮箱验证:</p>
        <a href=""{{VerificationLink}}"">验证邮箱</a>
    ";
}

发送时直接调用:

_emailService.SendEmail(user.Email, "重置密码", EmailTemplates.PasswordReset, new Dictionary<string, string>
{
    {"Username", user.Username},
    {"ResetLink", resetUrl}
});

三、封装特定邮件类型的方法(提高复用性)

为了让业务代码调用更简洁,可以在EmailService里封装特定邮件的发送方法:

public void SendPasswordResetEmail(string toEmail, string username, string resetLink)
{
    var template = _emailTemplateRepo.GetTemplate("PasswordReset");
    var variables = new Dictionary<string, string>
    {
        {"Username", username},
        {"ResetLink", resetLink}
    };
    SendEmail(toEmail, "重置你的密码", template, variables);
}

public void SendVerificationEmail(string toEmail, string username, string verificationLink)
{
    var template = _emailTemplateRepo.GetTemplate("EmailVerification");
    var variables = new Dictionary<string, string>
    {
        {"Username", username},
        {"VerificationLink", verificationLink}
    };
    SendEmail(toEmail, "请验证你的邮箱", template, variables);
}

业务代码里直接调用_emailService.SendPasswordResetEmail(...)即可,无需重复处理模板和变量。

四、额外建议

  • 把SMTP配置(主机、端口、账号密码)放到appsettings.json中,通过依赖注入读取,避免硬编码。
  • 给邮件添加纯文本 fallback,用MultipartAlternative组合HTML和纯文本部分,兼容不支持HTML的邮箱。
  • 测试时用Mailtrap的预览功能,检查变量替换是否正确、HTML渲染是否符合预期。

内容的提问来源于stack exchange,提问作者Diego Velásquez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:13:25