Monday, July 27, 2020

Send emails from ASP.NET Core websites using SendGrid and Azure

Today we have multiple free options to send email from our apps. Let's review how to configure and use SendGrid and Azure to send mail emails from our ASP.NET Core apps and benefit from their extraordinary free plan.
Photo by Carol Jeng on Unsplash

Long are the days that we had to use Gmail App Passwords to send and test emails from our apps. Today we have a plethora of alternatives that cost nothing or close to nothing. On that category, SendGrid offers Azure subscribers 25,000 free emails per month! So let's review how to setup a free SendGrid account and build a simple ASP.NET website to send emails from it.

On this post we will:
  • create a SendGrid account directly in Azure
  • build a simple ASP.NET Core web app and review how to properly configure it
  • access and configure our SendGrid settings in SendGrid
  • send emails using SMTP (not the RESTful API) from our console application
For a quick start, download the code from GitHub at: github.com/hd9/aspnet-sendgrid

Creating a SendGrid account in Azure

The good news is that in case you don't have one already, you can create a SendGrid account directly from Azure. Let's get straight to it. Open your Azure portal and type sendgrid on the search tool bar and click on SendGrid Accounts:
Click Add to create our account from Azure:
Enter your information on the next screen:
Review and confirm your package:
Wait until your deployment completes (it should take no more than 10 seconds). Now go back to SendGrid Accounts and you should see your new account there:
Clicking on it would take you to the SendGrid pane showing you essential information about your new resource:
Did you notice that Manage button? Clicking that button will take us directly to SendGrid where we'll be able to configure out account, create api keys, monitor our usage and a lot more.

I won't expand much in what SendGrid offers (tldr; a lot!). For more of that, feel free to visit their website.

Configuring SendGrid

The first time you login to SendGrid, you'll be requested to confirm your email address. After confirmation, this is the what you should see a screen similar to the below, showing you a general overview of your account:

Creating our SMTP Api Key

To be able to send emails from SendGrid, we'll have first to generate a password. First click on Settings -> API Keys:
Choose Restricted Access:

Select Mail Send (for this demo we only need that one):

And click create. You'll be presented with your password (api key). Copy it safely:

SendGrid Configuration

With the password in hand, here's a summary about the configuration we'll need:
  • Host: smtp.sendgrid.net
  • Port: 587
  • Username: apikey
  • Password: SG.zGNcZ-**********************

Building our App

I guess that at this point, creating an ASP.NET web app is no surprise to anyone. But if you're new to .NET Core, please check this documentation on how to build and run ASP.NET Core on Linux. It's a different perspective from the Visual Studio-centric approach you'll see elsewhere. To quickly create with VS, File -> Create a new project and select Web Application (Model-View-Controller).

Configuring our App

With the configuration in hand, let's now review how to use it. To simplify things, I built already a simple web app that captures 2 fields: name and email of a potential newsletter subscriber. It looks like this and is available on GitHub:
Apart from the visual, there are a couple of things on this app that are worth looking into. Let's start with the configuration. If you open appsettings.json on the root of the project you will see:
  "SmtpOptions": {
    "Host": "<smtp>",
    "Port": "587",
    "Username": "<account>",
    "Password": "<password>",
    "FromName": "<from-name>",
    "FromEmail": "<from-email>",
    "EmailOverride": "<email>"
  },
  "EmailTemplate": {
    "Subject": "[HildenCo WebStore] Welcome to our newsletter!",
    "Body": "Hello {0},\nThanks for signing up for our newsletter!\n\nBest Regards,\nHildenCo."
  }

Since I already explained how to bind that config to a class of our own, I'll not extend too much on the topic. Essentially we will:
  • map the SmtpOptions configuration into a SmtpOptions class
  • map the EmailTemplate config into the EmailConfig class
That mapping is done elegantly by the framework as this line from Startup.cs shows:
cfg = configuration.Get<AppConfig>();
Inspecting cfg during debug confirms the successful binding:

Dependency Injection

Next, it's time to setup dependency injection. For our objective here, ASP.NET's default DependencyInjection utility is good enough. Put the below in your ConfigureServices method to wire everything up:
services.AddSingleton(cfg.SmtpOptions);
services.AddSingleton(cfg.EmailTemplate);
services.AddTransient<IMailSender, MailSender>();
Next, inject the dependencies needed by our Controller and our MailSender classes:
readonly IMailSender _mailSender;
readonly ILogger<HomeController> _logger;

public HomeController(
    IMailSender mailSender,
    ILogger<HomeController> logger)
{
    _logger = logger;
    _mailSender = mailSender;
}

Invoking SendMail from our controller

To call MailSender from our controller, simply inject a SendMail command into and invoke it:
await _mailSender.Send(new SendMail
{
    Name = signup.Name,
    Email = signup.Email
});

Our MailSender class

To finish, here's an excerpt of our MailSender class (see the full source on GitHub):
// init our smtp client
var smtpClient = new SmtpClient
{
    Host = _smtpOptions.Host,
    Port = _smtpOptions.Port,
    EnableSsl = true,
    DeliveryMethod = SmtpDeliveryMethod.Network,
    UseDefaultCredentials = false,
    Credentials = new NetworkCredential(_smtpOptions.Username, _smtpOptions.Password)
};
// init our mail message
var mail = new MailMessage
{
    From = new MailAddress(_smtpOptions.FromEmail, _smtpOptions.FromName),
    Subject = _tpl.Subject,
    Body = string.Format(_tpl.Body, msg)
};
// send the message
await smtpClient.SendMailAsync(mail);

Testing the App

Run the app with Visual Studio 2019, enter a name and an email address. If all's configured correctly, you should soon get an email in your inbox:
As well as SendGrid reporting a successful delivery:

Final Thoughts

The only remaining question is why SMTP? The advantages of using SMTP instead of the API is that SMTP is a pretty standard protocol, works with .NET's primitives, works with any programming language or framework and, contrary to the restful API, does not require any specific packages. SMTP also works well with containers, but I'll leave that fore a future post. 😉

Conclusion

On this tutorial we reviewed how to create a SendGrid account directly from Azure, we demoed how to configure it so we can send emails from our applications. SendGrid is a great email service with a very powerful API that I recommend you exploring it and learning things such as creating your own templates, using webhooks, understanding how to review your usage, etc. On the future we'll revisit this example to send email from our own ASP.NET containers in a microservice application. Keep tuned!

Source Code

As always, the source is available on GitHub at: github.com/hd9/aspnet-sendgrid

References

See Also

Any comment or suggestion about this post? Please DM me on Twitter at @BrunoHilden