Using MailKit To Send And Receive Email In ASP.net 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!

I Got Exception XYZ

SMTP can sometimes be a bit tricky getting right in terms of SSL, TLS, and ports. Worse yet, the exception messages are often either cryptic, or start pushing you in the completely wrong direction. I created another article here, that should cover any sort of exception you might get when using this code.

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.

24 comments

  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 asp.net 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.

    1. I am trying to implement the same however, i am unable to Can you point me to a walk through that i can see my errors. Need to used this concept for email confirmation and other email within the application

    2. According to you post i am have the same result connecting to an exchange server for both ture and false
      False: SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection.

      The SSL certificate presented by the server is not trusted by the system for one or more of the following reasons:
      1. The server is using a self-signed certificate which cannot be verified.
      2. The local system is missing a Root or Intermediate certificate needed to verify the server’s certificate.
      3. The certificate presented by the server is expired or invalid.

      1. Usually I see this when you are trying to force SSL when the port only supports TLS. Change the “Connect” line to this :

        emailClient.Connect([hostname], [port]);

  4. Hi,
    MailKit is completely new to me. Is it possible to use MailKit in VBSCRIPT? I have done some googgling but with no luck. /Mats

  5. New to AspNet Core 2…How to new up EmailService? How do you pull in the required EmailConfiguration if you are storing it in appsettings.json?

    1. Hi Tom,

      ASP.net Core has inbuilt dependency injection.

      So all you need to do is on your controller, inject the service you need into it (That you registered with the ConfigureServices method). So for example :

      public class HomeController : Controller
      {
      private readonly IEmailService _emailService;
      public HomeController(IEmailService emailService)
      {
      _emailService = emailService;
      }
      ....
      }

  6. ‘EmailMessage’ does not contain a definition for ‘Content’ and no extension method ‘Content’ accepting a first argument of type ‘EmailMessage’ could be found (are you missing a using directive or an assembly reference?)

    Where is content supposed to be defined?

  7. Hi guys, im receiving that error message when I execute de app

    An unhandled exception occurred while processing the request.
    InvalidOperationException: Unable to resolve service for type ‘MandaEmail40.Models.EmailServico’ while attempting to activate ‘MandaEmail40.Controllers.EnviaEmailController’.

    Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired)

    any tip about ?

    1. You’re probably going to have to create a Github gist so I can see what’s going on here. If I had to guess, It’s because you are doing this :

      But then in your controller it looks something like :

      You need to inject the interface not the class. So :

Leave a Reply

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