Alos.Email.Validation
1.2.1
dotnet add package Alos.Email.Validation --version 1.2.1
NuGet\Install-Package Alos.Email.Validation -Version 1.2.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="Alos.Email.Validation" Version="1.2.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Alos.Email.Validation" Version="1.2.1" />
<PackageReference Include="Alos.Email.Validation" />
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 Alos.Email.Validation --version 1.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Alos.Email.Validation, 1.2.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 Alos.Email.Validation@1.2.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=Alos.Email.Validation&version=1.2.1
#tool nuget:?package=Alos.Email.Validation&version=1.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Alos.Email.Validation
Email validation library for anti-abuse protection in SaaS applications.
Features
- Format Validation - HTML5 Living Standard compliant email format validation
- Provider-Specific Normalization - Gmail dots/plus, Outlook plus, ProtonMail plus, etc.
- Relay Service Blocking - Apple Hide My Email, Firefox Relay, DuckDuckGo, SimpleLogin, etc.
- Disposable Domain Detection - 38,000+ known disposable email providers
- MX Record Verification - DNS-based domain validation with fail-open strategy
- MX Whitelist - Bypass MX validation for test/development domains
- Custom Blocklist/Allowlist - Override built-in lists with your own domains
- Hot-Reload - Runtime blocklist updates without redeployment
- Auto-Update - Background service for periodic blocklist updates from GitHub
- Thread-Safe - All operations are safe for concurrent access
Installation
dotnet add package Alos.Email.Validation
Quick Start
// Register services
builder.Services.AddEmailValidation(builder.Configuration);
// Or with auto-update
builder.Services.AddEmailValidationWithAutoUpdate(builder.Configuration);
{
"EmailValidation": {
"BlocklistDirectory": "/var/lib/alos/email-blocklists",
"EnableAutoUpdate": true,
"UpdateInterval": "1.00:00:00",
"InitialUpdateDelay": "00:00:30",
"CustomBlocklist": ["spammer.com"],
"CustomAllowlist": ["legitimate-service.com"],
"CustomBlocklistUrls": ["https://example.com/my-blocklist.txt"],
"CustomAllowlistUrls": ["https://example.com/my-allowlist.txt"],
"WhitelistedMxDomains": ["test.local", "itest.alos.local"]
}
}
API Reference
IEmailValidationService
| Method | Description |
|---|---|
ValidateEmailAsync(email, ct) |
Full async validation: format + relay + disposable + MX |
ValidateMxAsync(email, ct) |
MX record validation only (use when other checks done separately) |
ValidateFormat(email) |
Synchronous HTML5 format validation |
IsRelayService(email) |
Check if email uses a relay/forwarding service |
IsDisposable(email) |
Check if email domain is disposable |
Normalize(email) |
Get provider-normalized form for uniqueness checks |
Usage Patterns
Full Validation (All-in-One)
public class RegistrationService(IEmailValidationService emailValidator)
{
public async Task<bool> RegisterAsync(string email, CancellationToken ct)
{
// Full async validation (format + relay + disposable + MX)
var result = await emailValidator.ValidateEmailAsync(email, ct);
if (!result.IsValid)
{
// result.Error: InvalidFormat, RelayService, Disposable, InvalidDomain
return false;
}
// Get normalized email for uniqueness checks
var normalized = emailValidator.Normalize(email);
// Continue with registration...
return true;
}
}
With FluentValidation (Split Validation)
When using FluentValidation for synchronous checks, use ValidateMxAsync in your handler
to avoid duplicating validation:
// Validator (synchronous checks)
public class RegisterCommandValidator : AbstractValidator<RegisterCommand>
{
public RegisterCommandValidator(IEmailValidationService emailValidator)
{
RuleFor(x => x.Email)
.NotEmpty()
.Must(emailValidator.ValidateFormat).WithMessage("Invalid email format")
.Must(e => !emailValidator.IsRelayService(e)).WithMessage("Relay services not allowed")
.Must(e => !emailValidator.IsDisposable(e)).WithMessage("Disposable emails not allowed");
}
}
// Handler (async MX check only)
public class RegisterCommandHandler(IEmailValidationService emailValidator)
{
public async Task<Result> Handle(RegisterCommand cmd, CancellationToken ct)
{
// MX validation only (format/relay/disposable already validated)
var mxResult = await emailValidator.ValidateMxAsync(cmd.Email, ct);
if (!mxResult.IsValid)
return Result.Failure(Errors.InvalidDomain);
// Continue with registration...
}
}
Individual Checks
// Format validation (synchronous)
if (!emailValidator.ValidateFormat(email))
return Error("Invalid email format");
// Relay service check
if (emailValidator.IsRelayService(email))
return Error("Relay services not allowed");
// Disposable domain check
if (emailValidator.IsDisposable(email))
return Error("Disposable emails not allowed");
// Normalization for uniqueness
var normalized = emailValidator.Normalize(email);
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
BlocklistDirectory |
string | null | Directory for blocklist files |
EnableAutoUpdate |
bool | false | Enable background blocklist updates |
UpdateInterval |
TimeSpan | 1 day | Interval between blocklist updates |
InitialUpdateDelay |
TimeSpan | 30s | Delay before first update |
CustomBlocklist |
string[] | [] | Additional domains to block |
CustomAllowlist |
string[] | [] | Domains to exclude from blocking |
CustomBlocklistUrls |
string[] | [] | URLs to fetch blocklists from |
CustomAllowlistUrls |
string[] | [] | URLs to fetch allowlists from |
WhitelistedMxDomains |
string[] | [] | Domains that bypass MX validation |
WhitelistedMxDomains
Use this option to whitelist domains that should bypass MX validation (e.g., test domains without real DNS records):
{
"EmailValidation": {
"WhitelistedMxDomains": ["test.local", "itest.alos.local", "example.com"]
}
}
Whitelisted domains:
- Return success from
ValidateMxAsyncwithout DNS lookup - Return success from
ValidateEmailAsyncfor MX check (other checks still apply) - Are matched case-insensitively
Components
| Component | Description |
|---|---|
IEmailValidationService |
Orchestrates all validation checks |
IDisposableEmailDomainChecker |
Disposable domain detection with hot-reload |
IMxRecordValidator |
DNS MX record verification |
EmailNormalizer |
Static class for provider-specific email normalization |
RelayServiceBlocklist |
Static class blocking 21+ relay/forwarding services |
Framework Support
- .NET 8.0
- .NET 9.0
- .NET 10.0
License
Apache-2.0 License
| Product | Versions 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 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- DnsClient (>= 1.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net8.0
- DnsClient (>= 1.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
-
net9.0
- DnsClient (>= 1.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Http (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.