如何用FluentEmail和SendGrid在C#.NET中发送邮件

347 阅读8分钟

你可以用框架自带的**.NET**库来发送电子邮件,比如System.Net.Mail命名空间的API。它们适用于这种开发,然而,有时你需要一种更直接、更强大的方式来生成和发送电子邮件。

在这篇文章中,你将学习如何使用FluentEmail 库与Twilio SendGrid连接,在**.NET**的控制台 项目中生成和发送电子邮件。

创建一个控制台项目

你将需要使用.NET CLI创建一个控制台项目。打开一个控制台终端,运行以下命令,创建一个包含你的项目的文件夹:

mkdir SendGridFluentEmailSender
cd SendGridFluentEmailSender

接下来,用下面的命令创建该项目:

dotnet new console

配置SendGrid

在SendGrid中配置一个单一的发送者

为了通过Twilio SendGrid发送电子邮件,你需要验证一个电子邮件地址或域名的所有权,以便该服务能够代表你发送消息。为了快速上手,你将在本教程中使用单一发件人验证。这将验证你拥有应用程序将发送邮件的电子邮件地址。单一发件人验证对于测试来说是很好的,但不建议用于生产。

Twilio建议生产环境使用域名认证。一个经过认证的域名可以向电子邮件提供商证明你拥有该域名,并删除 "通过sendgrid.net "的文字,否则收件箱提供商会将其附加到你的发件地址上。

要做到这一点,请进入发件人认证选项,然后在单一发件人验证部分,选择开始

Page of the "Sender Authentication" submodule, specifically in the "Single Sender Verification" section and with the option to start with the "Get Started" button.

填写表格,在发件人 字段中指定你将发送邮件的电子邮件地址。这必须是一个你可以访问的电子邮件地址,因为你会收到一封验证邮件。

Create a Sender form, asking the user for the "From Name", "From Email Address", "Reply To", "company address", "City" and "Country" as required data, with other fields as optional.

创建发件人后,你将收到一封电子邮件,确认你对指定电子邮件地址的所有权。

Page with message "Sender had been created" and a button to "Resend email" to verify the single sender email address.

几秒钟或几分钟后会有一封电子邮件到达,其中有一个链接,你必须访问该链接以确认和验证你对现有邮箱的所有权。找到该邮件并点击验证单一发件人

Email received from SendGrid requesting to verify the ownership of the existing email address. The email has a button to click "Verify Single Sender".

当通过你收到的链接验证电子邮件地址时,你会看到一个确认页面,稍后你就可以在发件人列表中看到你的电子邮件地址已经被验证,并准备好从SendGrid发送电子邮件。

Confirmation page after clicking in the verification email, with the message "Sender Verified"

Page displaying the Sender you configured, indicating that it is verified for use.

创建一个API密钥

你需要创建一个API密钥来使用Twilio SendGrid发送邮件。

首先,访问你的SendGrid账户,并导航到 "设置"下的API密钥页面。

Screen for API Keys option in Settings, with the button "Create API Key" to create a new key for using in your project.

接下来,点击创建API密钥,并在显示的表格中输入一个名称,以区别于其他项目的密钥,给它限制性访问权限,只有邮件发送权限。

Create API Key form with a text field for the name and a radio button for the permission. In this project, the name is SendGridFluentEmailSender and the permission radio button is selected for the Restricted Access option

Create API Key form with the Mail Send accordion opened and with the Mail Send is a toggle and is enabled

滚动到表格的底部,点击创建和查看。在下一个屏幕上,你将看到你必须复制的 API密钥(你以后将在项目中使用它)。

Page displaying the API Key created in plain text to copy, indicating that it will not be displayed again for security.

在项目中添加API密钥

要在**.NET项目中添加一个密钥,你有几个选择,比如直接在代码中做(不推荐),在项目中做一个配置文件**,在你的应用程序所在的系统中作为一个环境变量,或者作为一个用户秘密。你将使用用户秘密,因为它是本地开发的一个很好的选择,易于管理,更安全,并遵循良好的开发实践

要为你的项目设置用户秘密,请在你的项目根文件夹内的命令行上运行以下命令:

dotnet user-secrets init
dotnet user-secrets set "SendGridApiKey" "<SendGrid API Key created>"

用你之前复制的API密钥替换<SendGrid API Key created>

要从.NET加载用户秘密,你需要添加Microsoft.Extensions.Configuration.UserSecrets NuGet 。使用以下命令为用户秘密添加包:

dotnet add package Microsoft.Extensions.Configuration.UserSecrets

接下来,在你的项目中,在Program.cs文件中,用以下内容替换所有现有代码:

using Microsoft.Extensions.Configuration;

IConfigurationRoot configuration = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();
string sendGridApiKey = configuration["SendGridApiKey"];

上面的代码从你创建的用户秘密库中导入SendGrid的API密钥。

发送电子邮件

.NET有几个发送电子邮件的选项,其中一个著名的选项是FluentEmail,它通过某些类和方法简化了电子邮件模板的开发和发送电子邮件。要使用它,你需要在你的新项目中安装该库,方法是在项目文件夹内运行以下命令:

dotnet add package FluentEmail.SendGrid

截至本文写作时,FluentEmail.SendGrid库的最新可用版本是3.0.2。

在配置和安装好一切之后,你现在必须更新你的控制台项目,以便从你的单一发送者电子邮件地址发送一封示例邮件。要做到这一点,用以下代码更新Program.cs类:

using FluentEmail.Core;
using FluentEmail.Core.Models;
using FluentEmail.SendGrid;
using Microsoft.Extensions.Configuration;

IConfigurationRoot configuration = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();
string sendGridApiKey = configuration["SendGridApiKey"];

IFluentEmail fluentEmail = Email
    .From("<sender email address>")
    .To("<destination email address>")
    .Subject("Test Email")
    .Tag("test")
    .Body("This is a test email using Twilio SendGrid and FluentEmail");

SendGridSender sendGridSender = new SendGridSender(sendGridApiKey);
SendResponse response = sendGridSender.Send(fluentEmail);

if (response.Successful)
{
        Console.WriteLine("The email was sent successfully");
}
else
{
    Console.WriteLine("The email could not be sent. Check the errors: ");
    foreach (string error in response.ErrorMessages)
    {
        Console.WriteLine(error);
    }
}

用你先前配置的单发人电子邮件地址替换<sender email address> ,用你希望的收件人替换<destination email address>

另外,在创建电子邮件时,在代码中调用Tag() 方法。这个方法允许你指定一个或几个类别来跟踪Twilio SendGrid中邮件的状态。例如,在统计模块中的类别统计部分,你可以看到一个仪表盘,并通过你正在创建的电子邮件中指定的标签来过滤它。

Dashboard "Category Stats" to view the status of sent emails filtered by the category associated with each email when creating it.

现在,运行你的控制台项目来发送你的第一封电子邮件:

dotnet run

要在Visual Studio Code中运行该项目,请按Ctrl + F5 来运行。

几秒钟后,一封邮件就会到达收件人的邮箱,类似于下面的内容。

Email received with the text "Test Email" as subject, "this is a test email using Twilio SendGrid and FluentEmail" as body.

使用Razor模板来生成电子邮件

你的项目已经开始工作了,但你可以通过使用Razor模板生成HTML来改进电子邮件的正文。要做到这一点,你可以在电脑上的一个路径或在项目本身中创建一个C# Razor(.cshtml)文件。

运行下面的命令,将Razor支持添加到FluentEmail:

dotnet add package FluentEmail.Razor

FluentEmail中的Razor模板渲染是RazorLight的实现,这个库允许你在ASP.NET Core MVC以外的项目中使用Razor,比如你正在做的这个控制台项目。

也可以使用Liquid,另一个渲染引擎(由Shopify提供),通过FluentEmail.Liquid NuGet包提供。

首先,创建一个类,称为TestEmailModel.cs,它将存储你可以在发送前添加到模板中的属性。在这种情况下,你将只添加Name 属性:

namespace SendGridFluentEmailSender
{
    public class TestEmailModel
    {
        public string Name { get; set; }
    }
}

然后,创建一个Razor文件TestEmail.cshtml,并添加以下Razor代码:

@model SendGridFluentEmailSender.TestEmailModel

This is a test email using <strong>Twilio SendGrid</strong> and <strong>FluentEmail</strong> created by @Model.Name

然后,更新Program.cs文件,将正文从纯文本改为Razor模板:

using FluentEmail.Core;
using FluentEmail.Core.Models;
using FluentEmail.Razor;
using FluentEmail.SendGrid;
using Microsoft.Extensions.Configuration;
using SendGridFluentEmailSender;

IConfigurationRoot configuration = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();
string sendGridApiKey = configuration["SendGridApiKey"];

Email.DefaultRenderer = new RazorRenderer();

IFluentEmail fluentEmail = Email
    .From("<sender email address>")
    .To("<destination email address>")
    .Subject("Test Email")
    .Tag("test")
    .UsingTemplateFromFile($"<path for CSHTML file>", new TestEmailModel { Name = "<Your Name>" });

SendGridSender sendGridSender = new SendGridSender(sendGridApiKey);
SendResponse response = sendGridSender.Send(fluentEmail);

if (response.Successful)
{
    Console.WriteLine("The email was sent successfully");
}
else
{
    Console.WriteLine("The email could not be sent. Check the errors: ");
    foreach (string error in response.ErrorMessages)
    {
            Console.WriteLine(error);
    }
}

如果文件不在你的项目文件夹中,则将<path for CSHTML file> 改为文件的完整路径,如果在项目文件夹中,则为相对路径,同时,用你的名字或任何你想添加的文本替换<Your Name>

接下来,打开SendGridFluentEmailSender.csproj文件,在PropertyGroup 部分添加值为true的PreserveCompilationContext 属性:

<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PreserveCompilationContext>true</PreserveCompilationContext>
</PropertyGroup>

PreserveCompilationContext 属性被设置为true,内容和资源文件在编译过程中被保留下来,因此你可以在程序执行过程中使用它们。在这个项目中,PreserveCompilationContext 必须为真,这样TestEmail.cshtml文件才能在运行时被复制和使用。

再次运行你的项目:

dotnet run

你将得到一封应用了HTML标签和数据模型的邮件:

Body of the message with the text "This is a test email using Twilio SendGrid and FluentEmail created by Nestor Campos", displayed with the corresponding HTML tags marking "Twilio SendGrid" and "FluentEmail" in bold.

来自SendGrid的动态电子邮件模板

除了你可以在你的项目中创建模板,为你发送的每封邮件提供合适的设计外,另一个解决方案是使用Twilio SendGrid的动态邮件模板。动态电子邮件模板将允许你添加你自己的设计或使用默认的电子邮件的可用设计。你可以自己通过图形用户界面或用代码创建模板。这些模板使用**Handlebars模板语言**来创建动态电子邮件模板,并将数据注入你的电子邮件中。而且就像项目内的模板一样,你可以将你的数据添加到模板中,以定制交付给你的每个用户的内容。

根据你的需要,将模板存储在SendGrid中而不是你的源代码中可能是有益的,所以你可以随时更新它而不必重新部署你的.NET应用程序。最重要的是,FluentEmail通过SendWithTemplateAsync() (源代码)的方法,使得使用这些模板变得很容易。

未来的改进

这是一个很好的开始,但你可以进一步改进这个解决方案:

  • 使用Razor Layout文件来重复使用页眉和页脚。布局允许不同的Razor文件共享一个类似的结构。例如,你所有的电子邮件模板都可以有相同的标题,上面有你公司的标志,侧面有一个部分,页脚有你公司的联系信息,而在中央部分,将有每个模板的代码和具体数据。这将帮助你保持你的电子邮件的总体设计与每个模板的具体数据分开。
  • 如果你自动发送邮件,你应该跟踪哪些邮件被发送,以避免再次发送,并以过多的邮件给你的用户/客户带来不便。