Skip to content
Starten Sie mit 100 kostenlosen Verifizierungs-Credits
Qualisend
Alle Artikel
Engineering / 13. Juni 2026

E-Mail-Adressen in C# validieren

7 minutes read

Qualisend team
Ein C#-Codefenster, das eine E-Mail über die Schichten Syntax, DNS und SMTP validiert

Um eine E-Mail-Adresse in C# zu validieren, greifen die meisten Entwickler zu System.Net.Mail.MailAddress und machen weiter. Das ist ein vertretbarer erster Schritt — der Typ ist im Framework eingebaut und weist Müll ohne selbst gebaute Regex zurück —, aber er beantwortet nur die erste der drei Fragen, die echte Validierung stellt. Ist die Adresse korrekt geformt? Kann ihre Domain Mail empfangen? Existiert das Postfach tatsächlich? Die .NET-Basisklassenbibliothek beantwortet die erste Frage sauber, benötigt für die zweite ein bekanntes NuGet-Paket und überlässt die dritte einem Netzwerkproblem, das man besser auslagert. Dieser Leitfaden baut E-Mail-Validierung in C# als drei Schichten auf, jeweils mit idiomatischem async/await-Code, und zeigt genau, wo MailAddress aufhört.

Die kurze Antwort#

Verwenden Sie MailAddress.TryCreate für die Syntax, das Paket DnsClient.NET für den MX-Lookup und eine Verifizierungs-API für die SMTP-Postfachprüfung — das Günstigste zuerst, mit Kurzschluss, sobald eine Schicht entscheidend ist. Öffnen Sie keine rohen SMTP-Sockets aus Ihrer App, um Postfächer selbst zu prüfen: Der ausgehende Port 25 ist auf den meisten Hosts blockiert, und die Antwort hängt von der Reputation der sendenden IP und von Greylisting ab, das Sie nicht neu implementieren wollen. Jede Schicht schließt Adressen günstiger aus als die vorige; nur die letzte kann eine Adresse einschließen. Wenn Sie nur ein Verdikt für eine einzelne Adresse brauchen, fügen Sie sie in den kostenlosen E-Mail-Checker ein und überspringen Sie den Code — der Rest dieses Leitfadens dient dazu, die Prüfung in eine App einzubauen. Die Konzepte hinter jeder Stufe finden Sie unter was E-Mail-Verifizierung ist.

Schicht 1: Syntax mit MailAddress.TryCreate#

MailAddress ist das richtige Werkzeug für Schicht eins. Bevorzugen Sie die in .NET 5 hinzugefügte Überladung TryCreate: Sie gibt bei fehlerhafter Eingabe einen bool zurück, statt eine FormatException zu werfen, sodass Sie darauf prüfen können, ohne jeden Aufruf in ein try/catch zu verpacken.

using System.Net.Mail;

public static bool IsValidSyntax(string email)
{
    return !string.IsNullOrWhiteSpace(email)
        && email.Length <= 320
        && MailAddress.TryCreate(email, out var parsed)
        && parsed.Address == email;
}
IsValidSyntax("jane@example.com");           // true
IsValidSyntax("not-an-email");               // false
IsValidSyntax("Jane <jane@example.com>");    // false

Dieser letzte Vergleich ist wichtig. MailAddress ist ein Mail-Parser, kein strenger Validator — er akzeptiert bereitwillig Anzeigename-Formen wie Jane <jane@example.com> und legt den Adressteil über parsed.Address offen. Wenn Sie parsed.Address mit der rohen Eingabe vergleichen, weisen Sie solche Formen und versprengte Leerzeichen zurück — genau das, was Sie von einer Ja/Nein-Syntaxprüfung auf Benutzereingaben erwarten. Der Schutz auf 320 Zeichen ist doppelt abgesichert: Nichts Längeres kann eine echte Adresse sein, und es ist günstiger, früh abzulehnen, als eine riesige Zeichenkette an nachgelagerte Verarbeitung zu übergeben.

Auf .NET Framework oder jedem Ziel älter als .NET 5 existiert TryCreate nicht, greifen Sie also auf den Konstruktor zurück und fangen Sie die Exception ab:

try { _ = new MailAddress(email); /* syntax ok */ }
catch (FormatException) { /* reject */ }

Wenn Sie bereits Data Annotations auf einem Modell verwenden, erledigt das System.ComponentModel.DataAnnotations.EmailAddressAttribute ([EmailAddress]) dieselbe Aufgabe deklarativ und ist eine gute Wahl innerhalb der Modellvalidierung von ASP.NET Core. Was auch immer Sie wählen: Behandeln Sie ein Bestehen als „lohnt sich, richtig zu prüfen“, niemals als „gültig“. Eine Syntaxprüfung weiß nichts über DNS oder Postfächer — aus demselben Grund scheitert Regex-basierte E-Mail-Validierung: Form und Zustellbarkeit sind unterschiedliche Fragen, die eine ist eine Tatsache über die Zeichenkette, die andere eine Tatsache über das Internet.

Schicht 2: Kann die Domain Mail empfangen?#

Eine Domain ohne Mail-Route kann für niemanden Mail annehmen, dieser eine Lookup eliminiert also tote Domains, falsch geschriebene Firmennamen und erfundene TLDs, bevor Sie das Netzwerk überhaupt richtig berühren. Der Haken: .NET hat keinen eingebauten MX-Resolver. System.Net.Dns löst A- und AAAA-Einträge auf, aber kein MX, die idiomatische Antwort ist also DnsClient.NET — ein weit verbreitetes, gut gepflegtes NuGet-Paket, zu dem die meisten .NET-Projekte greifen, wenn sie DNS über Host-Lookups hinaus brauchen. Installieren Sie es und fragen Sie den MX-Eintragstyp ab:

using System.Linq;
using DnsClient; // dotnet add package DnsClient

// LookupClient is thread-safe and caches responses — create one and reuse it.
private static readonly LookupClient Dns = new();

public static async Task<bool> HasMailRouteAsync(string domain)
{
    try
    {
        var response = await Dns.QueryAsync(domain, QueryType.MX);
        return response.Answers.MxRecords().Any();
    }
    catch (DnsResponseException)
    {
        // No reachable resolver, SERVFAIL, and similar — treat as "check later".
        return false;
    }
}
await HasMailRouteAsync("gmail.com");               // true
await HasMailRouteAsync("company-that-folded.com"); // false

Zwei nachahmenswerte Idiome. Erstellen Sie den LookupClient einmal und verwenden Sie ihn wieder — er ist thread-sicher und cacht Antworten, eine Instanz pro Anfrage wirft diesen Cache also einfach weg. Und trennen Sie die Domain am letzten @ mit einem Range-Ausdruck von der Adresse ab, damit Sie eine Adresse, die (rechtmäßig) mehr als ein @ enthält, nie falsch parsen:

var domain = email[(email.LastIndexOf('@') + 1)..];

Manche Domains nehmen Mail über einen A-Eintrag ohne MX an (ein implizites MX). Wenn Sie diesen Grenzfall berücksichtigen möchten, greifen Sie auf QueryType.A zurück, wenn die MX-Menge leer ist — aber für die überwältigende Mehrheit echter Adressen ist eine MX-Prüfung der richtige Filter. Eine Warnung für einen Anmeldepfad: Eine DNS-Abfrage blockiert an einem Resolver, ein vorübergehender DNS-Aussetzer sollte also keinen echten Kunden hart ablehnen. Behandeln Sie einen fehlgeschlagenen Lookup als „später prüfen“, nicht als „ungültig“.

Schicht 3: Existiert das Postfach tatsächlich?#

Schicht eins und zwei können eine Adresse nur ausschließen. Eine Domain kann perfekte MX-Einträge veröffentlichen und trotzdem kein Postfach an der Adresse haben, die Sie in der Hand halten — noreply-9f2x@gmail.com ist gültige Syntax auf einer Domain mit einer aktiven Mail-Route, und es ist trotzdem ein Postfach, das nie angelegt wurde. Zu bestätigen, dass ein bestimmtes Postfach existiert, bedeutet die SMTP-Zustellkonversation: sich mit dem Mailhost verbinden, RCPT TO absetzen, die Antwort lesen und die Verbindung trennen, bevor irgendetwas gesendet wird. Wie E-Mail-Verifizierung funktioniert geht diese vollständige Pipeline durch, einschließlich Catch-all-Domains, die jede Adresse annehmen und eine naive Prüfung aushebeln.

Im Prinzip können Sie das in C# mit einem TcpClient und rohen SMTP-Befehlen skripten. In der Praxis sollten Sie es nicht von Ihrem Anwendungsserver aus ausführen. Die meisten Cloud-Anbieter blockieren den ausgehenden Port 25, eine Prüfung, die auf Ihrem Laptop funktioniert, scheitert also im Produktivbetrieb still und leise. Die Antwort hängt von der Reputation der IP ab, von der aus Sie sich verbinden, nicht nur von der Adresse, die Sie prüfen. Und empfangende Server setzen unbekannte Absender auf Greylisting und Rate-Limits, Prüfen in jeglichem Volumen bringt Ihnen also Verzögerungen oder einen Eintrag auf Sperrlisten ein. Das ist die Schicht, die man an dafür gebaute Infrastruktur delegieren sollte.

Eine Verifizierungs-API aus C# aufrufen#

Der Verifizierungs-Endpunkt von Qualisend führt die gesamte Pipeline aus — Syntax, DNS und die SMTP-Postfachprüfung — von reputationsverwalteter Infrastruktur aus und liefert ein Verdikt in Echtzeit zurück. HttpClient plus System.Text.Json ist alles, was Sie brauchen; modellieren Sie den Antwort-Umschlag als Records und lassen Sie den JSON-Source-Generator oder den Reflection-Deserializer sie füllen:

using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Serialization;

public record VerifyResponse(
    [property: JsonPropertyName("result")] VerifyResult Result);

public record VerifyResult(
    [property: JsonPropertyName("status")] string Status,
    [property: JsonPropertyName("score")] int Score,
    [property: JsonPropertyName("reason")] string? Reason,
    [property: JsonPropertyName("sub_flags")] IReadOnlyDictionary<string, bool> SubFlags);
// One HttpClient for the whole app — don't new one up per request.
private static readonly HttpClient Http = new()
{
    BaseAddress = new Uri("https://api.qualisend.com/v1/"),
};

public static async Task<VerifyResult> VerifyAsync(string email)
{
    using var request = new HttpRequestMessage(HttpMethod.Post, "verify")
    {
        Content = JsonContent.Create(new { email }),
    };
    request.Headers.Authorization = new AuthenticationHeaderValue(
        "Bearer", Environment.GetEnvironmentVariable("QUALISEND_API_KEY"));

    using var response = await Http.SendAsync(request);
    response.EnsureSuccessStatusCode();

    var body = await response.Content.ReadFromJsonAsync<VerifyResponse>();
    return body!.Result; // status: deliverable | risky | undeliverable | unknown
}

POST https://api.qualisend.com/v1/verify ist eine Platzhalterform — prüfen Sie die API-Referenz unter /developers für den genauen Endpunkt, das Format des Scoped Keys und jedes Feld. Lesen Sie den Key aus einer Umgebungsvariable, statt YOUR_API_KEY fest zu codieren, und verwenden Sie einen einzigen HttpClient wieder, um Socket-Erschöpfung zu vermeiden. Die Antwort kommt in einem result-Umschlag zurück:

{
  "result": {
    "status": "deliverable",
    "score": 95,
    "reason": null,
    "sub_flags": { "role": false, "disposable": false, "free": false, "catch_all": false }
  }
}

status ist Ihr Kernverdikt — deliverable, risky, undeliverable oder unknown. score bewertet die Konfidenz, reason erklärt ein negatives Ergebnis, und sub_flags schlüsselt Signale wie Role, Disposable, Free und Catch-all auf, sodass Sie Ihre eigene Policy anwenden können (undeliverable ablehnen, risky zur Prüfung zurückhalten, disposable bei der Anmeldung markieren).

Die Schichten zusammensetzen, um eine E-Mail-Adresse in C# zu validieren#

Das Günstigste zuerst, aufhören, sobald Sie eine Antwort haben:

public static async Task<VerifyResult> ValidateEmailAsync(string email)
{
    if (!IsValidSyntax(email))
        return new VerifyResult("undeliverable", 0, "invalid_email",
            new Dictionary<string, bool>());

    var domain = email[(email.LastIndexOf('@') + 1)..];
    if (!await HasMailRouteAsync(domain))
        return new VerifyResult("undeliverable", 0, "invalid_domain",
            new Dictionary<string, bool>());

    return await VerifyAsync(email); // deliverable | risky | undeliverable | unknown
}

Die beiden lokalen Schichten kosten nichts und fangen den meisten Müll sofort ab; die API-Schicht läuft nur auf Adressen, die den Netzwerk-Roundtrip wert sind. Diese Reihenfolge ist der ganze Trick — dieselbe Form finden Sie in den Versionen dieses Leitfadens für Node.js, Python und PHP, denn es ist die Schichtung, nicht die Sprache, die Validierung funktionieren lässt.

Häufig gestellte Fragen#

Reicht MailAddress oder EmailAddressAttribute aus, um eine E-Mail in C# zu validieren?#

Für die Syntax ja — beide sind solide Prüfungen der ersten Schicht und die bessere Wahl gegenüber einer selbst gebauten Regex, wobei MailAddress.TryCreate Ihnen einen Boolean ohne Exception liefert. Sie validieren aber die Form, nicht die Zustellbarkeit: Keines von beiden löst DNS auf oder kontaktiert einen Mailserver, ein Bestehen bedeutet also „sieht aus wie eine E-Mail“, nicht „wird zugestellt“. Kombinieren Sie die Syntaxprüfung mit einem MX-Lookup und einer SMTP-Postfachprüfung, bevor Sie der Adresse vertrauen.

Bietet .NET eine eingebaute Möglichkeit, MX-Einträge abzufragen?#

Nein. System.Net.Dns löst A- und AAAA-Host-Einträge auf, unterstützt aber kein MX, weshalb der Standardansatz das NuGet-Paket DnsClient.NET ist. Fragen Sie QueryType.MX ab, verwenden Sie einen einzigen LookupClient wieder und behandeln Sie eine leere Antwortmenge — oder eine DnsResponseException — als fehlende Mail-Route, statt sie eine Exception werfen zu lassen.

Kann ich in C# ohne API prüfen, ob ein Postfach existiert?#

Nur teilweise. DnsClient.NET bestätigt, dass die Domain Mail annimmt, was tote Domains kostengünstig ausschließt. Das tatsächliche Postfach zu bestätigen bedeutet eine SMTP-Konversation, die Sie mit einem TcpClient versuchen können, aber nicht von Ihrem App-Server aus ausführen sollten — der ausgehende Port 25 ist weitverbreitet blockiert und das Ergebnis hängt von der Reputation Ihrer sendenden IP ab. Das ist die Schicht, für die es einen Verifizierungsdienst gibt, und es lohnt sich, Anbieter zu vergleichen, bevor Sie es selbst bauen.

Sollte ich E-Mails bei der Anmeldung oder beim Bereinigen einer Liste validieren?#

Beides, in unterschiedlicher Tiefe. Führen Sie Syntax und MX-Lookup bei der Anmeldung synchron aus — sie sind schnell genug, um die Anfrage zu blockieren und sofortiges Feedback zu geben — und handeln Sie auch dort nach dem unmittelbaren API-Verdikt; der Leitfaden zur serverlosen Anmeldung zeigt das Muster durchgängig. Reservieren Sie die tiefere, gebündelte Verifizierung für das Bereinigen einer bestehenden Liste, wo Latenz keine Rolle spielt, Gründlichkeit aber schon.


Bereit, die SMTP-Schicht hinzuzufügen? Die API-Referenz enthält die genaue /verify-Form, Scoped Keys und Copy-and-paste-Beispiele, oder werfen Sie eine Adresse in den kostenlosen E-Mail-Checker, um zu beobachten, wie eine von MailAddress genehmigte Zeichenkette als undeliverable zurückkommt.

Your reputation, protected.

Clean your first list in minutes. 100 free credits, no card required.

Get started