DEV Community

Adriรกn Bailador
Adriรกn Bailador

Posted on

Email Management with .NET 9 and C# using MailKit

๐Ÿ“Œ Introduction

Managing emails programmatically is a common requirement in many applications. In .NET 9, the SmtpClient class is obsolete and no longer recommended. Instead, MailKit and MimeKit provide a modern, efficient, and flexible way to handle email communication.

This guide will help you configure and use MailKit to send emails securely and efficiently.


โœ… 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)


๐Ÿ”ง Setting Up MailKit in C

1๏ธโƒฃ Install Required Package

Run the following command to install MailKit:

 dotnet add package MailKit
Enter fullscreen mode Exit fullscreen mode

2๏ธโƒฃ Securely Store SMTP Credentials

โŒ Bad practice: Hardcoding credentials in your code.
โœ… Good practice: Use environment variables:

Set Environment Variables (Windows/Linux/macOS)

export SMTP_HOST=smtp.example.com
export SMTP_PORT=587
export SMTP_USER=your-email@example.com
export SMTP_PASSWORD=your-password
Enter fullscreen mode Exit fullscreen mode

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");
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ค 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 a .NET 9 application." };

            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}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”’ SecureSocketOptions Overview

Option Description
None No encryption.
SslOnConnect Uses SSL/TLS immediately upon connection.
StartTls Starts unencrypted, then 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;
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ง Sending HTML Emails

message.Body = new TextPart("html")
{
    Text = "<h1>Welcome!</h1><p>This is a <strong>test email</strong> with HTML formatting.</p>"
};
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ฉ 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"));
Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Using OAuth2 Authentication (Recommended for Gmail, Outlook)

using MailKit.Security;
client.Authenticate(new SaslMechanismOAuth2(smtpUser, "your-access-token"));
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Š 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");
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”„ Enhancing Resilience with Retry Policies

Using Polly to implement retries on transient errors:

var retryPolicy = Policy.Handle<SmtpCommandException>()
    .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));
Enter fullscreen mode Exit fullscreen mode

โšก Sending Emails Asynchronously

For better performance in web applications:

await client.SendAsync(message);
await client.DisconnectAsync(true);
Enter fullscreen mode Exit fullscreen mode

โš™ 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

Option 1: Smtp4Dev (Local SMTP Server)

dotnet tool install -g Rnwood.Smtp4dev
smtp4dev
Enter fullscreen mode Exit fullscreen mode

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 the recommended way to send emails in .NET 9, replacing SmtpClient. It provides a modern and secure approach to email management.

๐Ÿ”น Best Practices: Use OAuth2 authentication, logging with Serilog, retry policies with Polly, and test with Smtp4Dev/Mailtrap to create a robust email-sending system.

Top comments (0)