Using MailKit To Send And Receive Email In Core

In previous posts I’ve talked about how you can now use the legacy SMTPClient class inside .NET to send emails. As commentators on this post have pointed out however, this has now been deprecated and the official documentation actually points you towards a very popular email library called “MailKit“. It’s open source, it’s super extensible, and it’s built on .NET Standard meaning that you can use the same code across .NET Full Framework, UWP and .NET Core projects.

Creating An Email Service

It’s always good practice that when you add in a new library, that you build an abstraction on top of it. If we take MailKit as an example, what if MailKit is later superceded by a better emailing library? Will we have to change references all over our code to reference this new library? Or maybe MailKit has to make a breaking change between versions, will we then have to go through our code fixing all the now broken changes?

Another added bonus to creating an abstraction is that it allows us to map out how we want our service to look before we worry about implementation details. We can take a very high level view of sending an email for instance without having to worry about exactly how MailKit works. Because there is a lot of code to get through, I won’t do too much explaining at this point, we will just run through it. Let’s go!

First, let’s go ahead and create an EmailAddress class. This will have only two properties that describe an EmailAddress.

Now we will need something to describe a simple EmailMessage. There are a tonne of properties on an email, for example attachments, CC, BCC, headers etc but we will break it down to the basics for now. Containing all of this within a class means that we can add extra properties as we need them later on.

Now we need to setup our email configuration. That’s our SMTP servers, ports, credentials etc. For this we will make a simple settings class to hold all of this. Since we are good programmers we will use an interface too!

Now we actually need to load this configuration into our app. In your appsettings.json, you need to add a section at the root for email settings. It should look something like this :

In the ConfigureServices method or your startup.cs, we can now pull out this configuration and load it into our app with a single line.

This allows us to inject our configuration class anywhere in our app.

The final piece of the puzzle is a simple email service that can be used to send and receive email. Let’s create an interface and an implementation that’s empty for now. The implementation should accept our settings object as a constructor.

Head back to our ConfigureServices method of our startup.cs to add in a final line to inject in our EmailService everywhere.

Phew! And we are done. If at this point we decided MailKit isn’t for us, we still have an email service that can swap in and out libraries as it needs to, and our calling application doesn’t need to worry about what’s going on under the hood. That’s the beauty of abstracting a library away!

Getting Started With MailKit

Getting started with MailKit is as easy as installing a Nuget package. Simply run the following from your Package Manager Console :

And hey presto! You now have access to MailKit in your application

Sending Email via SMTP With MailKit

Let’s head back to our email service class and fill out the “Send” method with the actual code to send an email via MailKit. The code to do this is below :

The comments should be pretty self explanatory, but let’s quickly run through it.

  • You can send clear text or HTML emails depending on the “TextFormat” you use when creating your message body
  • MailKit has named it’s Smtp class “SmtpClient” which is the same as the framework class. Be careful if you are using Resharper and the like that when you click “Add Reference” you are adding the correct reference.
  • You should choose to use SSL whenever available when connecting to the SMTP Server

Because we built out our EmailService, EmailMessage and EmailConfiguration classes earlier, they are all ready to be used immediately!

Receiving Email via POP With MailKit

And now the code to receive email via POP.

Again, all rather straight forward.

While we only retrieve a few basic details about the email message, the actual MailKit email object has a tonne of data you can inspect including headers, CC addresses, etc. Extend as you need to!

Free SMTP Server

It’s worth mentioning that if you are a hobbyist with your own website and want to just send a few emails every now and again under your own domain. A great solution that I use for this very blog is MailGun. It has a great free plan that for most people will be more than enough, but also paid plans for when you really need to start sending a lot of email.


  1. I used your excellent tutorial. It took 5 minutes to copy/paste, but 3 hours to figure out how to send an email by calling the public void Send from within a controller action.

    For others not yet aware of how to implement Dependency Injection. It would be good to know that you can inject within an ActionResult parameter like this:

    public IActionResult ForgetPW([FromServices] IEmailService Mailer)

    or at the controller level like this:

    public class ApiController : Controller {
    private readonly IEmailService _Mailer;
    public ApiController(IEmailService Mailer) {
    _Mailer = Mailer;

  2. Thanks for this, but I’m having trouble getting it to work. When I create the below code, I get Inconsistent Accessibility error on the public EmailService(… Any ideas what I’m doing wrong?

    public class EmailService : IEmailService
    private readonly IEmailConfiguration _emailConfiguration;

    public EmailService(IEmailConfiguration emailConfiguration)
    _emailConfiguration = emailConfiguration;

    1. Without seeing the rest of the code, Either IEmailConfiguration or IEmailService are not set to be public would be my guess 🙂

  3. Hi All, I think I have successfully implemented this now, but I still cannot send emails.

    emailClient.Connect(_emailConfiguration.SmtpServer, _emailConfiguration.SmtpPort, true);

    The program fails on the above line of code. I have tried it with both false and true for SSL, but it fails regardless.
    When set to true, I receive the following error – “IOException: The handshake failed due to an unexpected packet format.”
    When set to false, I receive the following error – “AuthenticationException: The remote certificate is invalid according to the validation procedure.”

    I have tried it a domain service that I use in another app (not core) to send emails and I have also tried gmail. Both seem to fail. I have also tried smtp port 25 and the ssl one 465.

    Any help is greatly appreciated.

Leave a Reply

Your email address will not be published. Required fields are marked *