Advanced email address validation in .NET

 
 
  • Gérald Barré

Applications often ask users to enter an email address, for instance to create an account. Of course, the application must check the value is a valid email address. In this post, we'll see how to validate the email address and avoid some typing mistakes.

#Check the value is an email address

First, we must check the user input is an email address. This means the value must match the grammar described in the RFC 5322 (which replaces RFC 2822 and RFC 822). There are 2 mains ways of validating email address: using a regex or a parser.

There are many regex on the web. Some are very complex (like this one), some are basics, and many are wrongs (reject valid values). I prefer using the regex provided by the W3C to validate <input type="email">:

C#
var regex = new Regex(@"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$", RegexOptions.Compiled);
return regex.IsMatch(email);

If you need a better parser, you can rely on the one provided by the .NET Framework. Indeed, you can parse an email address using the MailAddress class, which internally use MailAddressParser.

C#
// .NET 5
return MailAddress.TryCreate(email, out _);

// Before .NET 5
try
{
    var mailAddress = new MailAddress(email);
    return true;
}
catch (FormatException)
{
    return false;
}

#Check the domain has an email server

At this stage, you know the email address is valid, but this doesn't mean you'll be able to send an email at this address. If the user types "john@doe.dom" instead of "john@doe.com" (".dom" instead of ".com"), you may send an email to a domain that doesn't exist.

You can avoid this kind of typing errors by checking the provided domain exists and has an email server. Indeed, when you send an email to a recipient, you must first ask the IP address of the email server of the recipient. This information is provided by the DNS server, and more specifically the MX or A entry. For instance, the DNS of "meziantou.net" has one MX record:

meziantou.net.    A     149.56.135.50
meziantou.net.    MX    5 mx2.mail.ovh.net.
meziantou.net.    MX    100 mx3.mail.ovh.net.
meziantou.net.    MX    1 mx1.mail.ovh.net.

To query the DNS server in .NET, you can use the NuGet package DnsClient (NuGet, GitHub) which support .NET and .NET Core.

C#
Task<bool> IsValidAsync(string email)
{
    try
    {
        var mailAddress = new MailAddress(email);
        var host = mailAddress.Host;
        return CheckDnsEntriesAsync(host);
    }
    catch (FormatException)
    {
        return Task.FromResult(false);
    }
}

async Task<bool> CheckDnsEntriesAsync(string domain)
{
    try
    {
        var lookup = new LookupClient();
        lookup.Timeout = TimeSpan.FromSeconds(5);
        var result = await lookup.QueryAsync(domain, QueryType.Any).ConfigureAwait(false);

        var records = result.Answers.Where(record => record.RecordType == DnsClient.Protocol.ResourceRecordType.A ||
                                                     record.RecordType == DnsClient.Protocol.ResourceRecordType.AAAA ||
                                                     record.RecordType == DnsClient.Protocol.ResourceRecordType.MX);
        return records.Any();
    }
    catch (DnsResponseException)
    {
        return false;
    }
}

#Conclusion

You can quickly validate an email address by using a regex or a parser. If you want to go further, you can also query the DNS server of the recipient domain to ensure the domain exists and can receive emails. This allows detecting some typing mistakes in the domain part. However, this doesn't guarantee the email address exists. Indeed, the only way to ensure an email address exists is by sending an email.

#Additional resources

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub