These days sending emails like user email id confirmation, OTP emails, acknowledgments, etc. is a very common requirement of any application. In this article, we will see a demo about how to send emails in ASP.NET Core in quick & easy steps.
We will create an ASP.NET Core Web API project and add configuration as well as code to send emails using the MailKit library and my SMTP based email account.
MailKit is an open-source cross-platform mail client library that can be used in .NET or .NET Core applications running on Windows, Linux, or Mac.
Table of Contents
Implementation for Send Emails in ASP.NET Core
Here is the short & quick video about how to send emails in ASP.NET Core
Create new ASP.NET Core WebAPI Project
For this send emails in ASP.NET Core demonstration let’s create a new ASP.NET Core Web API project in which we will add an Email Service that can send emails using the MailKit library & SMTP Server.
SMTP Server or Simple Mail Transfer Protocol server are emails based application servers that allow you to send and receive mails between senders & receivers. For e.g. Gmail is an SMTP server. On registering for email service these servers provided you an email id account using which we can send/receive emails on that SMTP Server.
The SMTP server will have an address that will be used by email clients like MailKit to send emails in ASP.NET Core. Based on the SMTP email server being used to send mails you will have to obtain server details like Host, Port, etc., and configure the same in your application.
I will be using Visual Studio 2019 community edition along with .NET Core 5 to create a new Web API project as shown below
Add MailKit Nuget package to ASP.NET Core Project
Right-click on the ASP.NET Core project in solution explorer and select Manage NuGet Packages. On NuGet packages windows under the Browse tab search for MailKit. Install MailKit NuGet package as shown below
Add SMTP Server & Email Account details in appsettings.json file
To send an email we need SMTP server details using which we will connect to that server to send emails in ASP.NET Core. Also to access this SMTP server we will need security credentials to access that server i.e. details of the Email Account which has been created on that server to send emails will be required.
Now, these details should not be hardcoded in code as these are configurable parameters that can change over time so we will store the above details in the appsettings.json file. Not hardcoding the details in the code gives us the liberty to change these parameters without code changes.
Please note that the User Id & Password of the SMTP Server is very sensitive data and should not be stored in plain text in the appsettings.json file as it can be viewed by any person who has access to code or deployment environments. Instead, it should be securely stored somewhere so that it can be accessed only by unauthorized persons.
Here for demonstration purposes password is being stored in the appsettings.json file.
Lets add below details to appsettings.development.json file for SMTP Server & EMail Account.
"EmailSettings": { "EmailId": "support@procodeguide.com", "Name": "Support - Pro Code Guide", "Password": "MyPasswordForSMTPServer", "Host": "smtp.hostinger.in", "Port": 465, "UseSSL": true }
Read data from appsettings.json file
We have added all the required details to appsettings.development.json now let’s add code to read data from json file & make it available in the code to send emails in ASP.NET Core
We will be using Options Pattern along with Dependency Injection to read from json file into a class object
Add new class Configuration/EmailSettings.cs for json data as shown below
public class EmailSettings { public string EmailId { get; set; } public string Name { get; set; } public string Password { get; set; } public string Host { get; set; } public int Port { get; set; } public bool UseSSL { get; set; } }
Now to load data from appsettings.development.json file into an object of class EmailSettings at startup add the following line of code in Method ConfigureServices in Startup.cs file
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
The above line of code is using Configuration to read data from appsettings.development,json (as this is development environment) under section EmailSettings and loading this data into the object of type EmailSettings and this data will be available in controllers/services via Dependency Injection
In the below implementation of the email service, we will see how to get this data/object in Email Service using dependency injection.
Send basic text-based Email
Add Model & Email Service to Send Emails
Let’s add model for data required to send email i.e. Receiver Email Id, Subject & Body. This model will be input to Email Service which we will be adding to send emails.
public class EmailData { public string EmailToId { get; set; } public string EmailToName { get; set; } public string EmailSubject { get; set; } public string EmailBody { get; set; } }
Now, let’s add a service to send email using the MailKit library and SMTP Server. We will add Services/IEmailService.cs interface and Services/EmailService which implements this interface.
public interface IEmailService { bool SendEmail(EmailData emailData); }
public class EmailService : IEmailService { EmailSettings _emailSettings = null; public EmailService(IOptions<EmailSettings> options) { _emailSettings = options.Value; } public bool SendEmail(EmailData emailData) { try { MimeMessage emailMessage = new MimeMessage(); MailboxAddress emailFrom = new MailboxAddress(_emailSettings.Name, _emailSettings.EmailId); emailMessage.From.Add(emailFrom); MailboxAddress emailTo = new MailboxAddress(emailData.EmailToName, emailData.EmailToId); emailMessage.To.Add(emailTo); emailMessage.Subject = emailData.EmailSubject; BodyBuilder emailBodyBuilder = new BodyBuilder(); emailBodyBuilder.TextBody = emailData.EmailBody; emailMessage.Body = emailBodyBuilder.ToMessageBody(); SmtpClient emailClient = new SmtpClient(); emailClient.Connect(_emailSettings.Host, _emailSettings.Port, _emailSettings.UseSSL); emailClient.Authenticate(_emailSettings.EmailId, _emailSettings.Password); emailClient.Send(emailMessage); emailClient.Disconnect(true); emailClient.Dispose(); return true; } catch(Exception ex) { //Log Exception Details return false; } } }
In the above service, we have used the IOption interface in the constructor to inject the EmailSettings data object into the Service. This object contains SMTP server & Email Account data from json file which is being used to send an email to the specified recipient.
Now let’s register this service in the application container so that it can be injected into the controller using dependency injection. To add EmailService to the container add the following line of code n Method ConfigureServices in Startup.cs file
services.AddTransient<IEmailService, EmailService>();
Add Email Controller to call Email Service
Finally, we have to add an API endpoint method using which we will be able to send an email.
[ApiController] [Route("[controller]")] public class EmailController : ControllerBase { IEmailService _emailService = null; public EmailController(IEmailService emailService) { _emailService = emailService; } [HttpPost] public bool SendEmail(EmailData emailData) { return _emailService.SendEmail(emailData); } }
In the above email controller, I have added a post method SendEmail which takes EmailData as json input in the body. Also, dependency injection has been used to inject EmailService into the controller using constructor injection. EmailService has been used in the SendEmail action method to send emails in ASP.NET Core
Let’s Send the Email (run the code & test)
Select action /Email & click on the Try it out button to test send emails in ASP.NET Core
Enter the details for email id to, subject & body then click on execute button to call WebApi default post method /Email/SendEmail along with the entered data.
In the email account, we can see below that email has been delivered successfully
Send Emails in ASP.NET Core with Attachment
This is almost similar to text-based emails with the only change in the code being to add attachment file to BodyBuilder field Attachments as shown below in EmailService Code method SendEmailWithAttachment
Let’s first add a new EmailDataWithAttachment model class which derives from EmailData model class to take input of a file from a client calling the Action method to send an email with an attachment.
public class EmailDataWithAttachment : EmailData { public IFormFileCollection EmailAttachments { get; set; } }
Now let’s add a new action method in the Email controller to handle send emails in ASP.NET Core with attachments
[Route("SendEmailWithAttachment")] [HttpPost] public bool SendEmailWithAttachment([FromForm]EmailDataWithAttachment emailData) { return _emailService.SendEmailWithAttachment(emailData); }
We add one more method in IEmailService & implement the same in EmailService to handle send emails in ASP.NET Core with attachments
public interface IEmailService { bool SendEmail(EmailData emailData); bool SendEmailWithAttachment(EmailDataWithAttachment emailData); }
public bool SendEmailWithAttachment(EmailDataWithAttachment emailData) { try { MimeMessage emailMessage = new MimeMessage(); MailboxAddress emailFrom = new MailboxAddress(_emailSettings.Name, _emailSettings.EmailId); emailMessage.From.Add(emailFrom); MailboxAddress emailTo = new MailboxAddress(emailData.EmailToName, emailData.EmailToId); emailMessage.To.Add(emailTo); emailMessage.Subject = emailData.EmailSubject; BodyBuilder emailBodyBuilder = new BodyBuilder(); if(emailData.EmailAttachments != null) { byte[] attachmentFileByteArray; foreach(IFormFile attachmentFile in emailData.EmailAttachments) { if(attachmentFile.Length > 0) { using(MemoryStream memoryStream = new MemoryStream()) { attachmentFile.CopyTo(memoryStream); attachmentFileByteArray = memoryStream.ToArray(); } emailBodyBuilder.Attachments.Add(attachmentFile.FileName, attachmentFileByteArray, ContentType.Parse(attachmentFile.ContentType)); } } } emailBodyBuilder.TextBody = emailData.EmailBody; emailMessage.Body = emailBodyBuilder.ToMessageBody(); SmtpClient emailClient = new SmtpClient(); emailClient.Connect(_emailSettings.Host, _emailSettings.Port, _emailSettings.UseSSL); emailClient.Authenticate(_emailSettings.EmailId, _emailSettings.Password); emailClient.Send(emailMessage); emailClient.Disconnect(true); emailClient.Dispose(); return true; } catch (Exception ex) { //Log Exception Details return false; } }
Let’s run the code & check results for send emails in ASP.NET Core with attachments
Select action /Email/SendEmailWithAttachment & click on the Try it out button to test send emails in ASP.NET Core with attachments
Enter the details for email id to, subject, body & select attachment file then click on execute button to call WebApi function /Email/SendEmailWithAttachment along with the entered data.
In the email account, we can see below that email along with selected attachment has been delivered successfully
Send Emails in ASP.NET Core using Templates
HTML based templates for sending emails is useful when you want to send emails in ASP.NET Core for new users welcome, newsletter emails to users who have subscribed for newsletters, etc.
Let’s see a simple example of how to send emails in ASP.NET Core using templates. We will work on a simple HTML based email. We will add this HTML based template to our project make use of that for templated Emails.
Let’s add a welcome email template in Templates\WelcomeEmail.html as shown below
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Weclome to Pro Code Guide</title> </head> <body> <h1>Hello {0}</h1> <br/> <h3>{1}</h3> <br /> <p> We welcome you to our blog Pro Code Guide </p> <p>Thank You</p> </body> </html>
I am using a very basic html template for demonstration purpose you can have a rich template with HTML, CSS, Images, etc. as per your requirements
Since this is an email for the new users we will need the user name & user email id to send this mail. Email subject & body is not required as input as this is templated email so we know what will be the subject & body will be generated from Templates\WelcomeEmail.html
Let’s add new model for this which will have data fields User Name & User Email Id
public class UserData { public string UserName { get; set; } public string UserEmailId { get; set; } }
We will modify IEmailService & EmailService to have a new method SendUserWelcomeEmail to send a template-based email for welcome to the new users. Let’s add a definition for the new method SendUserWelcomeEmail in IEmailService
public interface IEmailService { bool SendEmail(EmailData emailData); bool SendEmailWithAttachment(EmailDataWithAttachment emailData); bool SendUserWelcomeEmail(UserData userData); }
Now we will implement this new method SendUserWelcomeEmail in EmailService which will make uses of Template Templates\WelcomeEmail.html & replace the place holders in template i.e. {0}, {1}, etc. with actual data and send the email in HTML format.
public bool SendUserWelcomeEmail(UserData userData) { try { MimeMessage emailMessage = new MimeMessage(); MailboxAddress emailFrom = new MailboxAddress(_emailSettings.Name, _emailSettings.EmailId); emailMessage.From.Add(emailFrom); MailboxAddress emailTo = new MailboxAddress(userData.UserName, userData.UserEmailId); emailMessage.To.Add(emailTo); emailMessage.Subject = "Welcome To Pro Code Guide"; string FilePath = Directory.GetCurrentDirectory() + "\\Templates\\WelcomeEmail.html"; string EmailTemplateText = File.ReadAllText(FilePath); EmailTemplateText = string.Format(EmailTemplateText, userData.UserName, DateTime.Now.Date.ToShortDateString()); BodyBuilder emailBodyBuilder = new BodyBuilder(); emailBodyBuilder.HtmlBody = EmailTemplateText; emailMessage.Body = emailBodyBuilder.ToMessageBody(); SmtpClient emailClient = new SmtpClient(); emailClient.Connect(_emailSettings.Host, _emailSettings.Port, _emailSettings.UseSSL); emailClient.Authenticate(_emailSettings.EmailId, _emailSettings.Password); emailClient.Send(emailMessage); emailClient.Disconnect(true); emailClient.Dispose(); return true; } catch (Exception ex) { //Log Exception Details return false; } }
Now let’s add a new action in Email Controller which will take this new model as input & call a new method in service SendUserWelcomeEmail to send template based email
[Route("SendUserWelcomeEmail")] [HttpPost] public bool SendUserWelcomeEmail([FromForm]UserData userData) { return _emailService.SendUserWelcomeEmail(userData); }
Let’s run the code & check results i.e. HTML template based email
Select action /Email/SendUserWelcomeEmail & click on the Try it out button to test send emails in ASP.NET Core with HTML templates
Enter the details for user name & user email id then click on execute button to call WebApi function /Email/SendUserWelcomeEmail along with the entered data.
Result – Below we can see the screenshot of the template based email received in the inbox of procoder@proocodeguide.com
Summary
In this article, we learned how to send emails in ASP.NET Core. We saw how to use the MailKit open-source library to send emails. I have added the GitHub link below to download the complete source code for this article.
We covered three types of emails i.e. simple text-based emails, emails with attachments & template-based emails like welcome messages, newsletters, etc.
I hope you liked this article, let me know your feedback in the comments section below
Download Source Code
Source code download for demo of Send emails in ASP.NET Core
https://github.com/procodeguide/ProCodeGuide.Sample.SendEmails
Do you have a tutorial on how to integrate MailKit with ASP.Net Core 5.0’s identity registration and email confirmation system?
Am I the only one who thinks that in 2021, with the latest Microsoft web development platform, sending email should be a tad easier than this?
You would think the kind of basic functions every web site needs, like sending an email, should be baked in, so it’s just one or two lines of code. I should not have to be created controllers and services and whatever else. If they really cannot do that, at least have these things set up from the start within the basic scaffolding that VS creates for a new web.
Every single web app is going to need this, so either make it super easy single line of code, or build it in from the default template. Don’t make us all figure out our own solutions that we need to include with every site.
It is easier to design a page to have the user set it up themselves to receive email from the amount of code required to implement a smtp client. As .net developer of 16 years it is still the same hoops and hurdles to cross when it comes to email. It should be this way because email is not a tool it is a weapon. In the wrong hands can bring down entire systems.
Hi
Thank you for the detailed explanation.
I build mms server and i need to send the mms by smtp client.
The body of the mms is a smil format.
how i can send smil include(eg image file) with this client.
Br
david tzur
Thanks for your feedback.. I will check on smil format and try to update my article for the same.
Hello,
I`ve downloaded the source of the demo from git, but it throws inner exception when I try to send an email but it throws inner exception on line 43 in EmailService: emailClient.Authenticate(_emailSettings.EmailId, _emailSettings.Password);
The exception says: + $exception {“535: 5.7.8 Error: authentication failed: UGFzc3dvcmQ6”} MailKit.Security.AuthenticationException
What could be the reason?
Thanks in advance!
You will have to configure (add details of) your SMTP server with a valid User Id & Password of your mail account using which email should be sent
How can I use this to create a contact form on my website please?
Do you have a contact form template that I can work with, and integrate into this project?
Hi Anthony.. You can create a simple cshtml page using which you can capture the required data and post it to the controller on form submission. In the controller, you can use that data to send an email using the email service.
Sanjay, thanks very much for the reply. I understand what you are suggesting. However, I do not have the expertise to design the contact page and to post the data to the EmailController.cs. The project works fine using the SwaggerUI (i.e. it sends emails to the desired email address). I just need a pre-configured cshtml ‘contact form’ page that I can use with the API. Can you point me in the right direction please? Alternatively, can you offer this as a service? I am happy to pay for your expertise and time.