Email Management with .NET 9 and C# using MailKit
Introduction
Dealing with emails by code is a must in many apps. In .NET 9, the SmtpClient
class is too old and not suggested anymore. Now, MailKit
and MimeKit
offer a new, fast, and bendy method for email talks. This piece looks at how to set up and use MailKit
in C# to send emails well and safe.
Prerequisites
Before implementing email-sending functionality, ensure you have:
- A .NET 9 application (Console, Web, or Windows Forms)
- An SMTP server (e.g., Gmail, Outlook, or your own SMTP service)
- Valid SMTP credentials (username and password) or an OAuth2 token
- Secure storage for credentials (environment variables, Azure Key Vault, AWS Secrets Manager, etc.)
Setting Up MailKit in C#
To send an email using MailKit
, follow these steps:
1. Install Required Package
Run the following command to install MailKit:
dotnet add package MailKit
2. Securely Store SMTP Credentials
Avoid hardcoding credentials in your code. Instead, use environment variables:
Set Environment Variables
export SMTP_HOST=smtp.example.com export SMTP_PORT=587 export SMTP_USER=your-email@example.com export SMTP_PASSWORD=your-password
Read Environment Variables in C#
var smtpHost = Environment.GetEnvironmentVariable("SMTP_HOST"); var smtpPort = int.Parse(Environment.GetEnvironmentVariable("SMTP_PORT")); var smtpUser = Environment.GetEnvironmentVariable("SMTP_USER"); var smtpPassword = Environment.GetEnvironmentVariable("SMTP_PASSWORD");
Sending an Email
using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; using System; class Program { static void Main() { try { var message = new MimeMessage(); message.From.Add(new MailboxAddress("Your Name", smtpUser)); message.To.Add(new MailboxAddress("Recipient", "recipient@example.com")); message.Subject = "Test Email"; message.Body = new TextPart("plain") { Text = "This is a test email sent from Codú." }; using var client = new SmtpClient(); client.Connect(smtpHost, smtpPort, SecureSocketOptions.StartTls); client.Authenticate(smtpUser, smtpPassword); client.Send(message); client.Disconnect(true); Console.WriteLine("Email sent successfully!"); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } }
Understanding SecureSocketOptions
None
: No encryption.SslOnConnect
: Uses SSL/TLS immediately upon connection.StartTls
: Starts with an unencrypted connection and upgrades to TLS (Recommended).Auto
: Automatically selects the best option.
Sending Emails with Attachments
var message = new MimeMessage(); message.From.Add(new MailboxAddress("Your Name", smtpUser)); message.To.Add(new MailboxAddress("Recipient", "recipient@example.com")); message.Subject = "Email with Attachment"; var body = new TextPart("plain") { Text = "Please find the attached file." }; var attachment = new MimePart("application", "pdf") { Content = new MimeContent(File.OpenRead("document.pdf"), ContentEncoding.Default), ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = "document.pdf" }; var multipart = new Multipart("mixed") { body, attachment }; message.Body = multipart;
Sending HTML Emails
message.Body = new TextPart("html") { Text = "<h1>Welcome!</h1><p>This is a <strong>test email from Codú</strong> with HTML formatting.</p>" };
Sending Emails to Multiple Recipients
message.To.Add(new MailboxAddress("Recipient1", "recipient1@example.com")); message.To.Add(new MailboxAddress("Recipient2", "recipient2@example.com")); message.Bcc.Add(new MailboxAddress("Hidden Recipient", "bcc@example.com"));
Using OAuth2 Authentication (Gmail, Outlook)
using MailKit.Security; client.Authenticate(new SaslMechanismOAuth2(smtpUser, "your-access-token"));
Implementing Logging with Serilog
using Serilog; Log.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/email.log", rollingInterval: RollingInterval.Day) .CreateLogger(); Log.Information("Email sent successfully to {Recipient}", "recipient@example.com");
Enhancing Resilience with Retry Policies
Using Polly
to implement retries on transient errors:
var retryPolicy = Policy.Handle<SmtpCommandException>() .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));
Sending Emails Asynchronously
For better performance in web applications:
await client.SendAsync(message); await client.DisconnectAsync(true);
Background Email Processing
For large-scale applications, consider:
- Hangfire (Task scheduling)
- Quartz.NET (Job scheduling)
- RabbitMQ / Azure Queue Storage (Message queuing)
Testing Email Sending with Smtp4Dev
or Mailtrap
To avoid sending real emails during development, use:
Option 1: Smtp4Dev (Local SMTP Server)
dotnet tool install -g Rnwood.Smtp4dev smtp4dev
Use localhost
as your SMTP server in testing.
Option 2: Mailtrap (Online Testing)
- Sign up at mailtrap.io
- Use the provided SMTP credentials in your
appsettings.json
or environment variables.
Conclusion
MailKit
is now the top choice for sending emails in .NET 9. It takes the place of the old SmtpClient
. This tool gives a new and safe way to handle emails. Keep key info like login details safe using things like environment variables, Azure Key Vault, or AWS Secrets Manager.
If you stick to good steps like using OAuth2 for login, keeping logs, trying again with Polly
, and testing with Smtp4Dev
or Mailtrap
, you can build a strong system for sending emails in your .NET apps.