CheapASPNETHostingReview.com | Best and Cheap ASP.NET Core 1.0 hosting. In this post I will show you how to send emails in ASP.NET Core 1.0 . ASP.NET Core 1.0 is a reboot of the ASP.NET framework which can target the traditional full .NET framework or the new .NET Core framework. Together,
ASP.NET Core and .NET Core have been designed to work cross platform and have a lighter, faster footprint compared to the current full .NET framework. Many of the .NET Core APIs are the same as they are in the full framework and the team have worked hard to try and keep things reasonably similar where it makes sense and is practical to do so. However, as a consequence of developing a smaller, more modular framework of dependant libraries and most significantly making the move to support cross platform development and hosting; some of the libraries have been lost. Take a look at this post from Immo Landwerth which describes the changes in more detail and discusses considerations for porting existing applications to .NET Core.
In this post, I will take you through how I got this working for the two scenarios I needed to tackle. Firstly, sending mail directly via an SMTP relay and secondly the possibility to save the email message into an SMTP pickup folder. Both turned out to be pretty painless to get going.
Adding MailKit to Your Project
The first step is to add the reference to the NuGet package for MailKit. I now prefer to use the project.json file directly to setup my dependencies. You’ll need to add the MailKit
library – which is at version 1.3.0-beta6 at the time of writing this post – to your dependencies section in the project.json file.
On a vanilla ASP.NET Core web application, your dependencies should look like this:
Once you save the change, VS should trigger a restore of the necessary NuGet packages and their dependencies.
Sending Email Via a SMTP Server
I tested this solution in a default ASP.NET Core web application project which already includes an IEmailSender
interface and a class AuthMessageSender
which just needs implementing. It was an obvious choice for me to test the implementation using this class as DI is already hooked up for it. For this post, I’ll show the bare bones code needed to get started with sending emails via an SMTP server.
To follow along, open up the MessageServices.cs file in your web application project.
We need three using
statements at the top of the file:
1 2 3 | using MailKit.Net.Smtp; using MimeKit; using MailKit.Security; |
The SendEmailAsync
method can now be updated as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public async Task SendEmailAsync(string email, string subject, string message) { var emailMessage = new MimeMessage(); emailMessage.From.Add(new MailboxAddress("Joe Bloggs", "jbloggs@example.com")); emailMessage.To.Add(new MailboxAddress("", email)); emailMessage.Subject = subject; emailMessage.Body = new TextPart("plain") { Text = message }; using (var client = new SmtpClient()) { client.LocalDomain = "some.domain.com"; await client.ConnectAsync("smtp.relay.uri", 25, SecureSocketOptions.None).ConfigureAwait(false); await client.SendAsync(emailMessage).ConfigureAwait(false); await client.DisconnectAsync(true).ConfigureAwait(false); } } |
First, we declare a new MimeMessage
object which will represent the email message we will be sending. We can then set some of its basic properties.
The MimeMessage
has a “from
” address list and a “to
” address list that we can populate with our sender and recipient(s). For this example, I’ve added a single new MailboxAddress
for each. The basic constructor for the MailboxAddress
takes in a display name and the email address for the mailbox. In my case, the “to
” mailbox takes the address which is passed into the SendEmailAsync
method by the caller.
We then add the subject string to the email message object and then define the body. There are a couple of ways to build up the message body, but for now I’ve used a simple approach to populate the plain text part using the message passed into the SendEmailAsync
method. We could also populate a Html body for the message if required.
That leaves us with a very simple email message object, just enough to form a proof of concept here. The final step is to send the message and to do that we use a SmtpClient
. Note that this isn’t the SmtpClient
from system.net.mail
, it is part of the MailKit
library.
We create an instance of the SmtpClient
wrapped with a using
statement to ensure that it is disposed of when we’re done with it. We don’t want to keep connections open to the SMTP server once we’ve sent our email. You can if required (and I have done in my code) set the LocalDomain
used when communicating with the SMTP server. This will be presented as the origin of the emails. In my case, I needed to supply the domain so that our internal testing SMTP server would accept and relay my emails.
We then asynchronously connect to the SMTP server. The ConnectAsync
method can take just the uri of the SMTP server or as I’ve done here be overloaded with a port and SSL option. For my case, when testing with our local test SMTP server, no SSL was required so I specified this explicitly to make it work.
Finally, we can send the message asynchronously and then close the connection. At this point, the email should have been fired off via the SMTP server.
Sending Email via a SMTP Pickup Folder
As I mentioned earlier, I also had a requirement to drop a message into a SMTP pickup folder running on the web server rather than sending it directly through the SMTP server connection. There may well be a better way to do this (I got it working in my test so didn’t dig any deeper) but what I ended up doing was as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public async Task SendEmailAsync(string email, string subject, string message) { var emailMessage = new MimeMessage(); emailMessage.From.Add(new MailboxAddress("Joe Bloggs", "jbloggs@example.com")); emailMessage.To.Add(new MailboxAddress("", email)); emailMessage.Subject = subject; emailMessage.Body = new TextPart("plain") { Text = message }; using (StreamWriter data = System.IO.File.CreateText("c:\\smtppickup\\email.txt")) { emailMessage.WriteTo(data.BaseStream); } } |
The only real difference from my earlier code was the removal of the use of SmtpClient
. Instead, after generating my email message object, I create a steamwriter
which creates a text file on a local directory. I then used the MimeMessage.WriteTo
method passing in the base stream so that the RFC822 email message file is created in my pickup directory. This is picked up and sent via the smtp system.