ASP.NET Core C# - Send email messages via SMTP with MailKit How to send e-mail messages from a ASP.NET Core C# web application through any SMTP server using the MailKit NuGet package

ASP.NET Core C# - How to lock an async method according to custom IDs

In this article I will briefly explain how to implement the IEMailSender interface using MailKit, which will allow any ASP.NET Web Application to send e-mail messages using any SMTP server.

For those who don't know what the IEmailSender interface and MailKit are, here's a brief explanation to better understand what are we talking about:

  • The IEmailSender interface is a set of ASP.NET native API that fully supports the ASP.NET Core Identity default UI infrastructure: such interface can be implemented by creating a custom EMailSender class that can be used within the Web Application to asynchronously send e-mail message in a structured, transparent and consistent way. For additional info, check out the IEmailSender interface official documentation and/or the Microsoft.AspNetCore.Identity.UI.Services namespace reference.
  • MailKit is an Open Source cross-platform .NET mail-client library based on MimeKit and optimized for mobile devices that allows to connect to SMTP server and send e-mail messages: for further details about it, check out its product page on NuGet.

In a nutshell, what we're about to do is to implement the IEmailSender interface using MailKit, so that we can use the native infrastructure to seamlessly send e-mail messages through the SMTP server of our choice. Are we ready? Let's start!

DISCLAIMER: This website is not affiliated with MailKit; this article represents the free opinion of the author and has not been commissioned or sponsored in any way.

1. Installing MailKit

The first thing we need to do is to install the MailKit NuGet package, which can be done in the following ways:

  • Using the .NET Core CLI, with the dotnet add package MailKit  console command from the ASP.NET Core project's root folder.
  • Using the Visual Studio Package Manager Console, by typing Install-Package MailKit  in the Package Manager window panel: if such panel is not already present in the default GUI it can be made accessible from the main menu (View > Other Windows > Package Manager Console).
  • Using the Visual Sutdio Package Manager GUI (from Solution Explorer, right-click to the project's root node and then select the Manage NuGet Packages option), as shown in the screenshot below.

ASP.NET Core C# - Send email messages via SMTP with MailKit

Once MailKit has been installed, we can move on to the next step.

2. Creating a TOptions class

If we don't want to "hardcode" the various required parameters to connect to the SMTP server (server name, protocol, credentials, and so on), we need to find a way to provide them to our IMailSender interface implementation: the most effective way  to do that is by leveraging the ASP.NET Core options pattern with a custom options class specifically made to host MailKit required variables, which we'll call MailKitEmailSenderOptions.

Here's how we can do that:

Needless to say, this is only a small example including the required stuff: we're free to add further properties if we need to configure additional parameters of our SMTP and/or e-mail message.

3. Implementing the MailKitEmailSender

Now that we can rely upon a configurable set of options we can implement the MailKitEmailSender class, which is the most important part of our work:

As we can see by looking at the above code, the class makes an extensive use of the MailKit NuGet Package to perform the SMTP connection and to actually send the e-mail message, taking all the required option from the MailKitEmailSenderOptions class and from the SendEmailAsync() method parameters.

4. Adding the MailKitEmailSender to the pipeline

Now that we have our very own MailKitEmailSender class, we need to add it to the web application's pipeline. This can be done by editing the Startup.cs file and adding the following statement block to the ConfigureServices() method:

This will make our web application aware of our custom EmailSender class during the startup phase and allow us to instantiate it in our Controllers using Dependency Injection.

If you need a SMTP service with a free plan you can visit SendInBlue.com and create a free account there, which allows to send up to 300 e-mail messages per day: should you choose do that, we strongly suggest to also read our tutorial on send email messages with SendInBlue and MailKit, which explains how to properly retrieve the required SMTP settings to feed the MailKitEmailSenderOptions class with.

Configure the SMTP settings from appsettings.json

In case you don't want to hardcode such values in the Startup.cs class - which would be quite undesiderable for a number of good reasons - you can define the SMTP settings in the appsettings.json file instead:

And then reference them to the Startup.cs class in the following way:

5. Sending the E-Mail message

Now that we've done all the required stuff, we just need to actually send a email message through our application. This can be done from any controller in the following way:

As we can see, we're accessing a IEmailSender instance through Dependency Injection in the SampleController'sconstructor, and then use it in the SendMail() action method below: such instance will be instantiated using the MailKitEmailSender implementation which we've added to the pipeline.

Conclusion

That's it, at least for the time being: I hope that this small tutorial will help other ASP.NET Core developers to implement their own MailKit-based EmailSender and send e-mail messages with ease!

UPDATE: We've recently written a follow-up post with an alternative implementation that takes advantage of the NETCore.MailKit NuGet package to achieve the same results in a faster way and with less custom code. You can find it here.
This article is part of the ASP.NET Core 5 and Angular book, available as paperback and e-book.

 

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

6 Comments on “ASP.NET Core C# - Send email messages via SMTP with MailKit How to send e-mail messages from a ASP.NET Core C# web application through any SMTP server using the MailKit NuGet package

  1. Hi Ryan,

    Thanks for the great article! I’ve just implemented the mailer following your code and it works perfectly. I would suggest a couple of improvements to the code though:

    (Minor fix) MailKitEmailSenderOptions class should not implement IOptions interface. Technically, it even can’t, since IOptions is a parametrized interface, so it just won’t work this way. Changing line 2 of MailKitEmailSenderOptions.cs to simple

    public class MailKitEmailSenderOptions

    works well.

    (Nitpicking) using MailKit.Security; is not needed in MailKitEmailSender.cs
    (Suggestion) As you mentioned yourself in part 2, hardcoding the configuration values is not a good way to go. Thus, I’d go one step further and instead of putting the configuration values into Startup.cs, I’d move to them to appsettings[.Development].json. While this might be slightly out of topic for this article, it won’t require much code changes, namely:

    Inject IConfiguration into Startup class, like this:


    public Startup(IConfiguration configuration)
    {
    Configuration = configuration;
    }

        public IConfiguration Configuration { get; }
    

    change the options reading code to e.g.

            services.AddTransient<IEmailSender, MailKitEmailSender>();
            services.Configure<MailKitEmailSenderOptions>(options =>
            {
                options.Host_Address = Configuration.GetValue<string>("SMTPSettings:HostAddress");
                options.Host_Port = Configuration.GetValue<int>("SMTPSettings:HostPort");
                options.Host_Username = Configuration.GetValue<string>("SMTPSettings:HostUsername");
                options.Host_Password = Configuration.GetValue<string>("SMTPSettings:HostPassword");
                options.Sender_EMail = Configuration.GetValue<string>("SMTPSettings:SenderEmail");
                options.Sender_Name = Configuration.GetValue<string>("SMTPSettings:SenderName");
            });
    

    And, finally, adding the actual configuration values to appsettings[.Development].json:

    {
    “Logging”: {

    }
    },
    “SMTPSettings”: {
    “HostAddress”: “my-smtp-server”,
    “HostPort”: 587,
    “HostUsername”: “my-smtp-username”,
    “HostPassword”: “my-smtp-password”,
    “SenderEmail”: “[email protected]”,
    “SenderName”: “My Sender Name”
    }
    }

    1. Hi Sergey,

      thanks a lot for your feedback! We’ve implemented all your suggestions in our post, which now looks even better :) However, we’ve also added an updated MailKit configuration technique that used the NETCore.MailKit NuGet package to achieve the same results in a faster and easier (albeit less configurable) way:

      https://www.ryadel.com/en/asp-net-core-send-email-messages-smtp-netcore-mailkit/

      That’s definitely a recommended approach for most scenarios, hence we strongly suggest you to read that as well.

      Thanks again,

      1. I’ve checked it out now – looks great indeed and requires much less boilerplate. Thanks for that second post!

  2. Beautiful. Just wanted to say thanks for the post. You explained IEmailSender integration for me.

    1. Thank you so much for the positive feedback! If you like our posts, feel free to follow us on our social networks :)

  3. Good article, thanks!

    FWIW, I think I’m going to go with the linked article (ASP.NET Core C# – Send email messages via SMTP using NETCore.MailKit) since according to the official docs for IEmailSender:

    This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used directly from your code. This API may change or be removed in future releases.

Leave a Reply

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


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.