CommunityAbp.AspNetZero.Emailing.Postmark
1.1.0
dotnet add package CommunityAbp.AspNetZero.Emailing.Postmark --version 1.1.0
NuGet\Install-Package CommunityAbp.AspNetZero.Emailing.Postmark -Version 1.1.0
<PackageReference Include="CommunityAbp.AspNetZero.Emailing.Postmark" Version="1.1.0" />
<PackageVersion Include="CommunityAbp.AspNetZero.Emailing.Postmark" Version="1.1.0" />
<PackageReference Include="CommunityAbp.AspNetZero.Emailing.Postmark" />
paket add CommunityAbp.AspNetZero.Emailing.Postmark --version 1.1.0
#r "nuget: CommunityAbp.AspNetZero.Emailing.Postmark, 1.1.0"
#:package CommunityAbp.AspNetZero.Emailing.Postmark@1.1.0
#addin nuget:?package=CommunityAbp.AspNetZero.Emailing.Postmark&version=1.1.0
#tool nuget:?package=CommunityAbp.AspNetZero.Emailing.Postmark&version=1.1.0
CommunityAbp.AspNetZero.Emailing.Postmark
A seamless integration module that enables Postmark email delivery services for AspNetZero and ABP Framework applications.
Overview
This package provides a robust implementation of email-sending capabilities using Postmark's API within the AspNetZero and ABP Framework ecosystem. It replaces the default transport (IEmailSender, normally MailKit) with Postmark's API while maintaining the simplicity and flexibility of ABP's modular architecture.
Features
- Drop-in replacement for ABP's default email sender
- Full support for Postmark's transactional email API
- Template management and synchronization
- Email tracking and analytics integration
- Comprehensive logging and monitoring
- Automatic retry handling for failed deliveries
- Support for both synchronous and asynchronous sending
- Batch email processing capabilities
Framework Support
Each ABP major line ships a single target framework, so the package multi-targets and picks the matching ABP dependency per TFM:
| Your app targets | Package asset used | ABP dependency | Where ABP comes from |
|---|---|---|---|
| net10.0 (AspNetZero 15.x) | net10.0 |
Abp >= 11.3.0 |
AspNetZero licensed feed only (see below) |
| net9.0 (AspNetZero 14.x) | net9.0 |
Abp >= 10.5.0 |
nuget.org |
| net8.0 (AspNetZero 13.x) | net8.0 |
Abp >= 9.4.2 |
nuget.org |
| netstandard2.0 / 2.1 | netstandard2.x |
Abp >= 9.4.2 |
nuget.org |
net10.0 consumers: the AspNetZero feed is required. ABP 11.x packages are not published to nuget.org; they exist only on the licensed AspNetZero NuGet feed (
https://nuget.aspnetzero.com/<your-key>/v3/index.json). Restoring this package'snet10.0asset will fail withNU1102: Unable to find package Abp with version (>= 11.3.0)until that feed is added to your solution'sNuGet.Config(AspNetZero 15.x solutions already have it). Older targets are unaffected.
Installation
dotnet add package CommunityAbp.AspNetZero.Emailing.Postmark
Quick Start
- Install the package
- Add the
Postmarksection toappsettings.json - Depend on
AbpPostmarkModuleand configure it inPreInitialize - Inject
IEmailSenderas usual; emails now go through Postmark
Configuration
{
"Postmark": {
"ApiKey": "your-api-key",
"FromAddress": "sender@yourdomain.com"
}
}
The package does not read IConfiguration itself; wire the values up in your module (this is the usual
AspNetZero *CoreModule or *ApplicationModule):
using Abp.Modules;
using CommunityAbp.AspNetZero.Emailing.Postmark;
[DependsOn(typeof(AbpPostmarkModule))]
public class MyProjectCoreModule : AbpModule
{
private readonly IConfigurationRoot _appConfiguration;
public MyProjectCoreModule(IWebHostEnvironment env)
{
_appConfiguration = AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
}
public override void PreInitialize()
{
Configuration.Modules.AbpPostmark().ApiKey = _appConfiguration["Postmark:ApiKey"];
Configuration.Modules.AbpPostmark().DefaultFromAddress = _appConfiguration["Postmark:FromAddress"];
Configuration.Modules.AbpPostmark().TrackOpens = true; // optional
}
}
AbpPostmarkModule replaces IEmailSender with PostmarkEmailSender (transient), so anything that already
injects IEmailSender (for example AspNetZero's UserEmailer) switches transport without code changes.
AspNetZero 15.x note
AspNetZero 15 moved email templates into the database (EmailTemplate entity + EmailTemplateProvider).
This package only replaces the transport, not the templates, so DB-backed templates keep working: the
rendered MailMessage is handed to Postmark as-is. Postmark-side templates (UseTemplate(...)) remain
available as an alternative.
Features
Email Sending
- Basic email sending support
- HTML and plain text email bodies
- Multiple recipients (To, CC, BCC)
- Custom From address support
- Default From address fallback from configuration
- Custom headers
Postmark Feature Support
- Postmark template integration
- Template ID support (numeric identifier)
- Template alias support (string identifier)
- Dynamic template model binding
- JSON serialization of template models
- Email open tracking
- Click tracking
- Tag support
Attachments
- File attachment support
- Multiple attachments per email
- Content-type detection
- Base64 encoding handling
- Stream position handling
Configuration & Setup
- Easy module integration with AbpModule
- Automatic dependency injection setup
- Configurable API key
- Configurable sender email
- Custom PostmarkClient configuration support
Logging & Diagnostics
- Structured logging throughout
- Debug level operational logs
- Information level success logs
- Error level failure logs
- Attachment processing logs
- Template usage logs
- Message ID tracking
Framework Support
- .NET Standard 2.0 / 2.1 (ABP 9.4.x)
- .NET 8.0 (ABP 9.4.x)
- .NET 9.0 (ABP 10.5.x)
- .NET 10.0 (ABP 11.3.x / AspNetZero 15.x)
Developer Experience
- Fluent API for template usage
- Extension methods for common operations
- Clear exception messages
- Consistent with ABP patterns
- Minimal configuration required
Not Yet Implemented
- Batch email sending
- Bounce handling
- Webhook support
- Message stream support
- Server-level configuration
- Retry policies
Postmark Templates
Template Identification
- Postmark supports two ways to identify templates:
TemplateId: A numeric identifier (e.g., 1234567)TemplateAlias: A string identifier (e.g., "welcome-email")
- These are stored in the mail headers using custom X-headers:
mail.Headers["X-Postmark-Template-Id"] = "1234567";
// OR
mail.Headers["X-Postmark-Template-Alias"] = "welcome-email";
Template Model
- The template model contains the variables that will be merged into your template
- It's stored as JSON in the mail body
- Example template model:
{
"userName": "John Doe",
"confirmationLink": "https://example.com/confirm/123",
"expiryDate": "2024-02-01"
}
Full Template Example
// Example 1: Using Template ID
var mail = new MailMessage();
mail.To.Add("user@example.com");
mail.UseTemplate(1234567, new {
userName = "John Doe",
confirmationLink = "https://example.com/confirm/123"
});
// Example 2: Using Template Alias
var mail = new MailMessage();
mail.To.Add("user@example.com");
mail.UseTemplate("welcome-email", new {
userName = "John Doe",
confirmationLink = "https://example.com/confirm/123"
});
Attachments
Here's an example of how to send attachments:
var mail = new MailMessage();
mail.To.Add("recipient@example.com");
mail.Subject = "Test with attachment";
// Adding a file attachment
mail.Attachments.Add(new Attachment("document.pdf", "application/pdf"));
// For templated emails with attachments
mail.UseTemplate("welcome-email", new { UserName = "John" });
await _emailSender.SendEmailAsync(mail);
Building from source
The repository's NuGet.Config references the AspNetZero feed as %ASPNETZERO_NUGET_URL% so the
per-customer URL is never committed. Set that environment variable before restoring:
export ASPNETZERO_NUGET_URL="https://nuget.aspnetzero.com/<your-key>/v3/index.json"
dotnet build
On Windows: setx ASPNETZERO_NUGET_URL "https://nuget.aspnetzero.com/<your-key>/v3/index.json" (then open a new shell).
CI reads the same value from the ASPNETZERO_NUGET_URL repository secret. Pull requests from forks do not
receive secrets, so their restore of the net10.0 target will fail; that is expected.
Versioning uses MinVer with a v tag prefix; pushing a vX.Y.Z tag
and publishing a GitHub release triggers the nuget.org push.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. Before submitting any changes, make sure to read our contribution guidelines.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Abp (>= 9.4.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Postmark (>= 5.2.0)
-
.NETStandard 2.1
- Abp (>= 9.4.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Postmark (>= 5.2.0)
-
net10.0
- Abp (>= 11.3.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Postmark (>= 5.4.1)
-
net8.0
- Abp (>= 9.4.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Postmark (>= 5.2.0)
-
net9.0
- Abp (>= 10.5.0)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.15)
- Postmark (>= 5.4.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Adds net9.0 (ABP 10.5.x) and net10.0 (ABP 11.3.x / AspNetZero 15.x) targets.
The net10.0 target depends on Abp 11.3.0, which is published only on the AspNetZero licensed NuGet feed
(not nuget.org). net10.0 consumers must add that feed to their NuGet.Config before restoring.
netstandard2.0 / netstandard2.1 / net8.0 targets are unchanged (Abp 9.4.x).
Public API (AbpPostmarkModule, Configuration.Modules.AbpPostmark(), PostmarkEmailSender) is unchanged.