Pixata.Email 3.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Pixata.Email --version 3.0.1
                    
NuGet\Install-Package Pixata.Email -Version 3.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Pixata.Email" Version="3.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Pixata.Email" Version="3.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Pixata.Email" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Pixata.Email --version 3.0.1
                    
#r "nuget: Pixata.Email, 3.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Pixata.Email@3.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Pixata.Email&version=3.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Pixata.Email&version=3.0.1
                    
Install as a Cake Tool

Pixata.Email Pixata.Email Nuget package

Pixata

An email service for use in .NET Core projects. Backed by Mailkit, it eases the effort needed to add email facilities to your project.

A Nuget package is available for this project.

Version 3.0.1 references a patched version of System.Security.Cryptography.Pkcs, as the one pulled in transitively had known vulnerabilities (GHSA-846f-f764-76mx, GHSA-2fmv-rv2c-59x7). No code changes.

Breaking changes

Version 3.0.0 changes how the connection to the SMTP server is secured. SmtpSettings has a new SocketOptions property (a MailKit SecureSocketOptions), and UseSsl is now a bool? marked [Obsolete]. If you set neither, the service uses implicit TLS on port 465 and required STARTTLS on any other port, where it used to try implicit TLS everywhere (which failed on port 587). See securing the connection below.

As from version 2.0.0, this package does not use LanguageExt, but returns an ApiResponse from the Pixata.Extensions package to indicate success or failure. See the comments at the bottom of this document for how this will change your code.

Setup

First thing you need to do is add your SMTP server and "From" details to your application. There are a few ways to do this, the most simple of which is to use appSettings.json...

  "Smtp": {
    "Server": "your.smtp.server",
    "Port": 999,
    "SocketOptions": "StartTls", // Optional, see below
    "UserName": "your.username",
    "Password": "your.password",
    "FromEmail": "jim@spriggs.com",
    "FromName": "Jim Spriggs",
    "ReplyTo": "jim@spriggs.com" // Optional
  }

Unless your name is Jim Spriggs, you'll need to change these to you own name and server settings!

Securing the connection

SocketOptions takes any member of MailKit's SecureSocketOptions enum (None, Auto, SslOnConnect, StartTls or StartTlsWhenAvailable). If you leave it out, the service picks one from the port...

Port Default
465 SslOnConnect (implicit TLS)
Anything else (eg 587, the standard submission port used by Microsoft 365, Gmail and most other providers) StartTls (required, so a man in the middle can't strip the encryption and see your credentials)

If you need an unencrypted connection (a local test server such as Papercut or smtp4dev, for example), set "SocketOptions": "None" explicitly.

Prior to version 3.0.0, the connection was controlled by a UseSsl flag, which MailKit maps to SslOnConnect (true) or StartTlsWhenAvailable (false). That meant true failed with a handshake error on port 587, and false only used STARTTLS if the server offered it. UseSsl still works, but is marked [Obsolete], and is ignored if you set SocketOptions. If you read UseSsl in your own code, note that it is now a bool?, and is null unless you set it.

Then add the following lines...

// .NET5 - Goes in Startup.cs
SmtpSettings smtpSettings = Configuration.GetSection("Smtp").Get<SmtpSettings>();
services.AddSingleton(smtpSettings);
services.AddTransient<PixataEmailService>();

// .NET6+ - Goes in Program.cs
SmtpSettings smtpSettings = builder.Configuration.GetSection("Smtp").Get<SmtpSettings>();
builder.Services.AddSingleton(smtpSettings);
builder.Services.AddTransient<PixataEmailService>();

This allows you to inject an instance of PixataEmailService into your code as usual, and it will have the settings baked in for you.

If you store your mail settings in secrets, environmental variables, etc, then you'll need to retrieve them from there and set up an instance of SmtpSettings from that.

If you are into interfaces, you can register that instead...

services.AddTransient<PixataEmailServiceInterface, PixataEmailService>();

Allowing multiple email servers or accounts

Note that this feature is only available from v1.2.4 onwards

If you need to be able to send emails from multiple servers or accounts, you can set up a default SmtpSettings as above, and then when you want to send from a different server or account, just change the SmtpSettings property on the service to use the appropriate settings...

SmtpSettings myStmpSettings = // Pick them up from wherever you store them
_emailService.SmtpSettings = myStmpSettings;

Usage

There are three overloads of the SendEmailAsync method. Easiest to use is a simple one that just takes the recipient's email address, the subject and the HTML body...

(await _emailService.SendEmailAsync("billy@shears.com", "Hello from Jim Spriggs", htmlBody)))
  .Match(_ => /* code on success */, ex => /* code on failure */);

If you want more control over what is sent and how, the second overload takes an EmailParameters object. The various constructors allow you to specify more detail, as well as adding multiple recipients. You can also add attachments, which are tuples of the form (string FileName, string MimeType, byte[] Data).

To copy the email to other people, add them to Cc or Bcc (both List<MailboxAddress>, empty by default), or use the AddCc and AddBcc methods, which parse the addresses the same way as the constructors do...

EmailParameters parameters = new EmailParameters("Your invoice", htmlBody, "billy@shears.com", "Billy Shears")
  .AddCc("accounts@shears.com")
  .AddBcc("jim@spriggs.com"); // Send me a copy

BCC recipients get the email, but don't appear in the headers that the other recipients see. CC and BCC were added in version 3.0.0.

See the EmailParameters code for more details.

The third overload takes an EmailParameters and a MailKit SecureSocketOptions, which overrides the one from your settings for this email only...

await _emailService.SendEmailAsync(emailParameters, SecureSocketOptions.StartTls);

The other two overloads connect using the socket options from your settings (see securing the connection), so you rarely need this one.

All three return an ApiResponse<Yunit>, so the failure message is the exception's message. The two overloads that use your settings prefix it with the exception type (eg "(AuthenticationException) Authentication failed"), as that is usually the useful part when a send fails.

Breaking change in version 2.0.0

As from version 2.0.0, the service uses an ApiResponse from the Pixata.Extensions package to indicate success or failure. Previous versions used LanguageExt, which has now been removed from this package.

If you are upgrading from a LanguageExt version, then you will need to change the code in the failure lambda. The LanguageExt version passed in a System.Exception, whereas the new version passes a string containing the error message. For example, you would change...

(await _emailService.SendEmailAsync("billy@shears.com", "Hello from Jim Spriggs", htmlBody)))
  // Note that ex is an Exception, so we need to use the Message property to get the details
  .Match(_ => /* code on success */, ex => Console.WriteLine(ex.Message));

...to...

(await _emailService.SendEmailAsync("billy@shears.com", "Hello from Jim Spriggs", htmlBody)))
  // Note that we use ex directly, as it is a string, not an Exception, so we don't have a Message property
  .Match(_ => /* code on success */, ex => Console.WriteLine(ex));

You will need also to make sure you wrap the first line in brackets (as shown above). This was not necessary before.

If your code captures the return value from SendEmailAsync in a local variable, then you will need to add a using statement for Pixata.Email and change the type of the variable from TryAsync<Unit> to ApiResponse<Yunit> (unless you use var in which case the compiler will correctly infer the return type). However, this is not a common pattern when using this service.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.1.0 83 10/19/2026
3.0.1 111 10/15/2026
3.0.0 351 10/6/2026
2.5.0 356 8/17/2026
2.3.0 165 7/19/2026
2.2.0 247 4/19/2026
2.1.0 198 3/8/2026
2.0.4 168 2/23/2026
2.0.3 157 2/23/2026
2.0.1 199 1/4/2026
2.0.0 194 1/4/2026
1.2.5 616 11/18/2024
1.2.4 342 9/23/2024
1.2.3 1,257 9/13/2023
1.2.1 461 2/22/2023
1.2.0 655 5/17/2022
1.1.0 637 4/10/2022
1.0.0 673 2/23/2022