CheckDisposable Emailcheckdisposable.email
← All guidesASP.NET Core guide · C#

Block disposable email signups in ASP.NET Core

Use a custom `ValidationAttribute` (sync) or call `IDisposableEmailChecker` from your controller action (async). The async approach is recommended.

The code

// Services/DisposableEmailChecker.cs
public interface IDisposableEmailChecker
{
    Task<bool> IsDisposableAsync(string email, CancellationToken ct = default);
}

public class DisposableEmailChecker(HttpClient http, IConfiguration cfg) : IDisposableEmailChecker
{
    public async Task<bool> IsDisposableAsync(string email, CancellationToken ct = default)
    {
        try
        {
            using var req = new HttpRequestMessage(HttpMethod.Get,
                $"https://api.checkdisposable.email/v1/check?email={Uri.EscapeDataString(email)}");
            req.Headers.Authorization = new("Bearer", cfg["CDE_KEY"]);
            using var res = await http.SendAsync(req, ct);
            if (!res.IsSuccessStatusCode) return false; // fail open
            var data = await res.Content.ReadFromJsonAsync<CheckResult>(cancellationToken: ct);
            return data?.is_disposable == true;
        }
        catch { return false; }
    }
    private record CheckResult(bool is_disposable);
}

// Program.cs
builder.Services.AddHttpClient<IDisposableEmailChecker, DisposableEmailChecker>();

// Controllers/AuthController.cs
[HttpPost("signup")]
public async Task<IActionResult> Signup(
    [FromBody] SignupRequest body,
    [FromServices] IDisposableEmailChecker checker)
{
    if (await checker.IsDisposableAsync(body.Email))
        return BadRequest(new { error = "Please use a real email address." });
    // ...create user
    return Ok(new { ok = true });
}

Notes

Why IHttpClientFactory
Registering via `AddHttpClient<>` gives connection pooling and prevents socket exhaustion. Never `new HttpClient()` per request.
Identity integration
If you use ASP.NET Identity, override `UserManager.CreateAsync` or use an `IIdentityResultErrorDescriber` to surface the disposable error in the same flow as other Identity errors.
Minimal APIs
The same `checker` is injectable into Minimal API endpoints — `app.MapPost("/signup", async (SignupRequest body, IDisposableEmailChecker c) => ...)`.

Get a free API key

500 checks/month, no credit card. No credit card. 30 seconds.

Sign up free →