How to send Email in C# .NET using SMTP and SendGrid

February 22, 2022
Written by
Reviewed by

Email has been around for decades, but sending emails at scale is still hard. With Twilio SendGrid, you can send emails without worrying about scalability. You can use the SendGrid APIs to send emails, but if you're already using SMTP in your code, you can also use the SMTP protocol with SendGrid. In this post, you will learn how to send emails using SMTP, SendGrid, and a .NET 6 console application.

This tutorial is built upon .NET 6, but all code works with older versions of .NET, including .NET Framework with minor adjustments.

Prerequisites

You will need the following things to follow along:

You can find the source code for this tutorial on GitHub. Use the source code if you run into any issues, or submit an issue on this GitHub repo, if you run into problems.

Configuring your SendGrid account to send emails

There are two things you need to configure before you can send emails. First, you’ll need to set up Sender Authentication. This will verify that you own the email address or domain that you will send emails from. Second, you’ll need to create a SendGrid API Key with permission to send emails.

Sender Authentication

It is recommended to configure Domain Authentication, which requires you to add a record to your DNS host. To keep things simple, you will use Single Sender Verification for this tutorial instead. This will verify that you own the single email address that you want to send emails from. Single Sender Verification is great for testing purposes, but it is not recommended for production.

Twilio recommends Domain Authentication for production environments. An authenticated domain proves to Inbox Service Providers you own the domain, and removes the "via sendgrid.net" text that inbox providers would otherwise append to your from address.

Click on the Settings tab in the left menu. Once the settings tab opens, click on Sender Authentication.

Side-navigation with a Settings group and multiple links in the group. The link "Sender Authentication" is highlighted.

Then, click Get Started under the Single Sender Verification section.

A button saying "Get Started" to verify an individual email address.

This will open a form on the right-side panel. Fill out the form with your information and email address.

A form to create a sender. The form asks for contact information including the email address that will be used to send emails from.

Click Create after filling out the form. Another panel will appear on the right, asking you to confirm your email address in your email inbox.
Go to your personal email inbox, open the email from SendGrid, and click Verify Single Sender.

An email from SendGrid with a button saying "Verify Single Sender".

Your email address has been verified. You can now use it to send emails!

Create a SendGrid API key to send emails

Back on the SendGrid website, click on API Keys under the Settings tab, then click on Create API Key in the top right-hand corner. This will open another form in the right-side panel. Give your API Key a useful name. You can assign different permissions to the API Key. For optimal security, you should only give the minimum amount of permissions that you need.
Next, click on Restricted Access.

A form to create an API Key. The form asks for a name for the key and what permissions to grant to the key.

Scroll down to the Mail Send accordion item and click on it to reveal the permissions underneath. Drag the slider to the right for the Mail Send permission.

A list of permissions that you can control using a slider bar next to each permission. The "Mail Send" accordion item is expanded to reveal the "Mail Send" permission underneath.

Scroll to the bottom of the form and click on Create & View. The API key will now be displayed on your screen. You will not be able to retrieve the API key again once you leave this screen, so make sure you copy the API Key somewhere safe.

API key is displayed to copy and store elsewhere. Key will not be shown again.

With the sender verified and the API Key created, you’re ready to write some code!

Create a console app to send emails

Create a new console app

Open a shell on your machine and create a new folder using the following command:

mkdir SendGridMailSmtp

Move into to the new folder:

cd SendGridMailSmtp

Create a new console application using .NET CLI:

dotnet new console

Run the project using the .NET CLI:

dotnet run

You should see “Hello, World!” output to your shell.

Send emails using MailKit and SendGrid

.NET has built-in APIs for sending emails using the SMTP protocol which are supported by Microsoft, but Microsoft recommends using the MailKit library for new development.

MailKit is an open-source and cross-platform library for sending emails and retrieving emails using the MAP, POP3, and SMTP protocols.

If you want to use the built-in SMTP .NET APIs with SendGrid, skip to the next section.

You'll need to add the MailKit NuGet package to start using the library. Run the following .NET CLI command to add the package:

dotnet add package MailKit

The version of the NuGet package at the time of writing this is 3.1.1.

Open up the SendGridMailSmtp project directory using a code editor and replace the contents of the Program.cs file with the following code:

using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;

using var message = new MimeMessage();
message.From.Add(new MailboxAddress(
    "[REPLACE WITH YOUR NAME]", 
    "[REPLACE WITH YOUR EMAIL]"
));
message.To.Add(new MailboxAddress(
    "[REPLACE WITH DESIRED TO NAME]", 
    "[REPLACE WITH DESIRED TO EMAIL]"
));
message.Subject = "Sending with Twilio SendGrid is Fun";
var bodyBuilder = new BodyBuilder
{
    TextBody = "and easy to do anywhere, especially with C#",
    HtmlBody = "and easy to do anywhere, <b>especially with C#</b>"
};
message.Body = bodyBuilder.ToMessageBody();

using var client = new SmtpClient();
// SecureSocketOptions.StartTls force a secure connection over TLS
await client.ConnectAsync("smtp.sendgrid.net", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync(
    userName: "apikey", // the userName is the exact string "apikey" and not the API key itself.
    password: Environment.GetEnvironmentVariable("SENDGRID_API_KEY") // password is the API key
);

Console.WriteLine("Sending email");
await client.SendAsync(message);
Console.WriteLine("Email sent");

await client.DisconnectAsync(true);

If you are using older versions or older templates of .NET, you will need to put the above code and any subsequent code inside the Main method of the Program class.

Update the placeholder strings:

  • replace "[REPLACE WITH YOUR EMAIL]" with the email address you verified with your SendGrid account.
  • replace "[REPLACE WITH YOUR NAME]" with your name.
  • replace "[REPLACE WITH DESIRED TO EMAIL]" with the email address you want to send an email towards.
  • replace "[REPLACE WITH DESIRED TO NAME]" with the recipient's name.

Save the Program.cs file.


The application will create an email message, connect to SendGrid's SMTP server, and send the email.

There are a couple important things to take note off:

  • The ​​BodyBuilder class is used to construct a MimeMessage that contains both the plain-text and the HTML version of the email body. If you only want to send plain-text emails or HTML emails, you can also do that as explained in MailKit's documentation.
  • The hostname of SendGrid's SMTP server is smtp.sendgrid.net and the recommended port is 587. There are other ports available as listed in the SendGrid documentation here.
  • The SecureSocketOptions.StartTls is passed as a parameter to the client.ConnectAsync method. SecureSocketOptions.StartTls will force the client to establish a secure connection over TLS. There are other options on the SecureSocketOptions enum that will also establish a secure connection over TLS, but this option will use TLS or throw an exception if it fails, as opposed to falling back to an insecure connection.
  • To authenticate against SendGrid's SMTP server, "apikey" – the string, not the API key itself – is used as the username, and the API key value is used as the password.
    The API key is retrieved from the environment variable which you will configure soon.
  • The SmtpClient class has synchronous alternatives for all the asynchronous methods used in the sample, in case you need it.

The application expects the API key to be stored in the SENDGRID_API_KEY environment variable.
Run the following command if you’re using a Bash or similar shell:

export SENDGRID_API_KEY=[REPLACE WITH YOUR API KEY]

Run the following command if you’re using PowerShell:

$Env:SENDGRID_API_KEY = "[REPLACE WITH YOUR API KEY]"

Run the following command if you're using CMD:

set SENDGRID_API_KEY=[REPLACE WITH YOUR API KEY]

The environment variable will be available for the duration of your shell session. You'll have to set the environment variable again when opening a new shell.

Run the project using the .NET CLI:

dotnet run

Once you see “Email sent” in the console, open the inbox of the recipient's email to verify if you’ve received the email. If you don't have access, you can use the Email Activity Feed to see the status of the email.
Here's what the email should look like:

An email with title "Sending with Twilio SendGrid is Fun" and body "and easy to do anywhere, especially with C#

Send emails using the built-in .NET APIs and SendGrid

Even though Microsoft recommends using the MailKit library to send emails, the APIs built into .NET are still supported and widely used. If you want to use the built-in SmtpClient with SendGrid, this is how you do it.

Open up the console project using a code editor or IDE and replace the contents of the Program.cs file with the following:

using System.Net;
using System.Net.Mail;
using System.Net.Mime;

using var message = new MailMessage();
message.From = new MailAddress(
    "[REPLACE WITH YOUR EMAIL]",
    "[REPLACE WITH YOUR NAME]"
);
message.To.Add(new MailAddress(
    "[REPLACE WITH DESIRED TO EMAIL]",
    "[REPLACE WITH DESIRED TO NAME]"
));
message.Subject = "Sending with Twilio SendGrid is Fun";
var textBody = "and easy to do anywhere, especially with C#";
var htmlBody = "and easy to do anywhere, <b>especially with C#</b>";

message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(
    textBody, null, MediaTypeNames.Text.Plain)
);
message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(
    htmlBody, null, MediaTypeNames.Text.Html)
);

// if you only want to send HTML email, simply use this
// message.Body = htmlBody;
// message.IsBodyHtml = true;

using var client = new SmtpClient(host: "smtp.sendgrid.net", port: 587);
client.Credentials = new NetworkCredential(
    userName: "apikey", // the userName is the exact string "apikey" and not the API key itself.
    password: Environment.GetEnvironmentVariable("SENDGRID_API_KEY") // password is the API key
);

Console.WriteLine("Sending email");
await client.SendMailAsync(message);
Console.WriteLine("Email sent");

If you are using older versions or older templates of .NET, you will need to put the above code and any subsequent code inside the Main method of the Program class.

Update the placeholder strings:

  • replace "[REPLACE WITH YOUR EMAIL]" with the email address you verified with your SendGrid account.
  • replace "[REPLACE WITH YOUR NAME]" with your name.
  • replace "[REPLACE WITH DESIRED TO EMAIL]" with the email address you want to send an email towards.
  • replace "[REPLACE WITH DESIRED TO NAME]" with the recipient's name.

Save the Program.cs file.


Just like the MailKit version, the application will create an email message, connect to SendGrid's SMTP server, and send the email.

There are a couple important things to take note off:

  • Using message.AlternateViews.Add you can add both plain-text and HTML versions of the email. If you only want to send plain-text or HTML emails, you can directly set the message body using message.Body and indicate whether the body is HTML via message.IsBodyHtml.
  • The hostname of SendGrid's SMTP server is smtp.sendgrid.net and the recommended port is 587. There are other ports available as listed in the SendGrid documentation here.
  • To authenticate against SendGrid's SMTP server, "apikey" – the string, not the API key itself – is used as the username, and the API key value is used as the password.
    The API key is retrieved from the environment variable, which you will configure soon, if you haven't configured it already in the previous section.
  • You can also send the message synchronously using client.Send.

If you haven't already done so in the last section, configure the SENDGRID_API_KEY environment variable.

Run the following command if you’re using a Bash or similar shell:

export SENDGRID_API_KEY=[REPLACE WITH YOUR API KEY]

Run the following command if you’re using PowerShell:

$Env:SENDGRID_API_KEY = "[REPLACE WITH YOUR API KEY]"

Run the following command if you're using CMD:

set SENDGRID_API_KEY=[REPLACE WITH YOUR API KEY]

The environment variable will be available for the duration of your shell session. You'll have to set the environment variable again when opening a new shell.

Run the project using the .NET CLI:

dotnet run

Once you see “Email sent” in the console, open the inbox of the recipient’s email to verify if you’ve received the email. If you don't have access, you can use the Email Activity Feed to see the status of the email.
Here's what the email should look like:

An email with title "Sending with Twilio SendGrid is Fun" and body "and easy to do anywhere, especially with C#

A note about configuring SmtpClient

These samples hard-code the hostname, the port, and username of the SendGrid SMTP service. Since the hostname and port won't change, this is fine, but typically in .NET applications, these values come from external configuration.

On the other hand, the API Key is pulled from the environment variables to avoid hard-coding this sensitive secret, but this also typically comes from external configuration in .NET applications.

To pull these values from external configuration in .NET (Core), you can use the ConfigurationBuilder or the HostBuilder which includes the former. Check out this Microsoft guide to add configuration to your console application.

For .NET Framework applications, you can use the mailSettings element in an app.config or web.config file to configure these values, as documented here.

Adding SendGrid headers to your SMTP emails

In addition to sending plain emails over SMTP, you can append additional headers to your email to add more SendGrid functionality. You can turn filters on/off, add substitution tags to swap tags with recipient specific data like first name, and categorize emails for analytics.

SendGrid has a handy C# .NET library to help you create these SendGrid headers for SMTP messages.

How to send SMTP emails in C# .NET using SendGrid

Sending emails using SMTP with SendGrid is mostly the same as sending emails with other SMTP servers:

  • Verify your email sender in the SendGrid app and create an API key.
  • Connect to SendGrid's SMTP server at smtp.sendgrid.net and use port 587.
  • Authenticate against the SMTP server using "apikey" as the username and the actual API key as the password.
  • Create your mail message and send it using the SmtpClient built into .NET or provided by the MailKit library.

Using the SMTP protocol makes it easy to move from your existing SMTP server to SendGrid's SMTP server for maximum scale and deliverability, but you can take advantage of more features by using the SendGrid C# .NET library which uses SendGrid's APIs instead of the dated SMTP protocol. If you want to switch from using SMTP to using SendGrid's APIs, follow this tutorial on how to send emails using the SendGrid APIs and the C# .NET library.

Additional resources

Check out the following resources for more information on the topics and tools presented in this tutorial:

SmtpClient documentation - The SmtpClient has been around for a very long time, so the samples are quite dated, but the documentation lists all the properties and methods you can use to send emails using SMTP.

MailKit documentation – The MailKit library can do a lot more than just send emails using SMTP, it can also send and retrieve emails using other protocols. Read more about its APIs in the MailKit documentation.

SendGrid C# .NET SDK on GitHub – This GitHub repository contains helpful documentation on how to integrate with SendGrid using .NET using SendGrid's .NET library.

Configure Console app on Microsoft Docs – You used environment variables to store the API Key in this tutorial, but it is recommended to use .NET's configuration APIs. Learn how to configure .NET console applications using the host builder.

Source Code to this tutorial on GitHub - Use this source code if you run into any issues, or submit an issue on this GitHub repo if you run into problems.

Niels Swimberghe is a Belgian American software engineer and technical content creator at Twilio. Get in touch with Niels on Twitter @RealSwimburger and follow Niels’ personal blog on .NET, Azure, and web development at swimburger.net.