Question

Like a good C# user, I use the MailAddress object to validate email addresses.

A client of mine entered john@gmail. for his email, which was validated by MailAddress, and broke my software. I'd expect the code below to throw an exception, but it doesn't.

static void Main(string[] args)
{
    string addressmail = string.Empty;

    try
    {
        MailAddress mail = new MailAddress(@"john@gmail.");
        addressmail = mail.Address;
    }
    catch (FormatException)
    {
        // address is invalid
    }

    // address is valid
    Console.WriteLine(addressmail);
}

Do you know how to catch this kind of bogus mail address?

Was it helpful?

Solution

I think in this case, MS's implementation of a valid email address is incorrect, at least as per RFC822. I haven't actually tried your code, so I'm assuming it does as you say.

There are other ways to validate email addresses, such as actually connecting to the SMTP server and asking it to confirm that the address is valid (as explained here and here). Short of doing that, you will always have a bit of trouble. Personally, I don't think that it's worthwhile to spend too much time validating email address according to some specification (beyond the quick checks we have at our disposal; e.g. your code) - the real test is whether an email is received on that address if you send it. A simple email verification can confirm this, although I know it might not be appropriate in all cases, but in those, you are out of luck.

OTHER TIPS

The MailAddress type has very limited support for validating email addresses and, as of .NET 4.0, does not support most of the related IETF standards. If you need to validate the syntax of your email addresses, possibly without using regular expressions, I suggest you to take a look at EmailVerify.NET, a .NET component that supports all of the current standards about the subject (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 and RFC 5322). Should you need to, the component even allows to perform additional tests on the addresses, including DNS, SMTP and mailbox checks.

Disclaimer: I am the lead developer for this product.

Somehow fixed version, mixing MailAddress and a simple Regex to validate the host:

Static regex, as advised by SLaks

private static readonly Regex hostReg = new Regex(@"(\w+)\.(\w+)");

public bool IsMailAddress(string addParam)
        {
            try
            {
                MailAddress mail = new MailAddress(addParam);
                string address = mail.Address;

                //not handled by MailAdress, which is a shame
                return hostReg.IsMatch(mail.Host);
            }
            catch (FormatException)
            {
                //address is invalid
                return false;
            }
            catch (Exception)
            {
                return false;
            }
        }

MailboxValidator has a free API which you can use. Just need to sign up for the free API plan at http://www.mailboxvalidator.com/plans#api then the integration part is pretty easy since they also have a C# class http://www.mailboxvalidator.com/dotnet for you to wrap the API calls.

The C# class codes are in https://github.com/MailboxValidator/mailboxvalidator-csharp

To install MailboxValidator SingleValidation class via NuGet (https://www.nuget.org/packages/MailboxValidator.SingleValidation/), run the following command in the Package Manager Console:

Install-Package MailboxValidator.SingleValidation

Then you can just use the class like below:

using System;
using System.Windows.Forms;
using MailboxValidator;

namespace TestMailboxValidatorCSharp
{
    public class TestMailboxValidatorCSharp
    {
        static void Main(string[] args)
        {
            var mbv = new SingleValidation("PASTE_YOUR_API_KEY_HERE");
            String results = "";
            try
            {
                MBVResult rec = mbv.ValidateEmail("example@example.com");

                if (rec.ErrorCode == "")
                {
                    results += "email_address: " + rec.EmailAddress + "\n";
                    results += "domain: " + rec.Domain + "\n";
                    results += "is_free: " + rec.IsFree + "\n";
                    results += "is_syntax: " + rec.IsSyntax + "\n";
                    results += "is_domain: " + rec.IsDomain + "\n";
                    results += "is_smtp: " + rec.IsSMTP + "\n";
                    results += "is_verified: " + rec.IsVerified + "\n";
                    results += "is_server_down: " + rec.IsServerDown + "\n";
                    results += "is_greylisted: " + rec.IsGreylisted + "\n";
                    results += "is_disposable: " + rec.IsDisposable + "\n";
                    results += "is_suppressed: " + rec.IsSuppressed + "\n";
                    results += "is_role: " + rec.IsRole + "\n";
                    results += "is_high_risk: " + rec.IsHighRisk + "\n";
                    results += "is_catchall: " + rec.IsCatchall + "\n";
                    results += "mailboxvalidator_score: " + rec.MailboxValidatorScore + "\n";
                    results += "time_taken: " + rec.TimeTaken + "\n";
                    results += "status: " + rec.Status + "\n";
                    results += "credits_available: " + rec.CreditsAvailable + "\n";
                }
                else
                {
                    results += "error_code: " + rec.ErrorCode + "\n";
                    results += "error_message: " + rec.ErrorMessage + "\n";
                }

                results += "version: " + rec.Version + "\n";
                MessageBox.Show(results);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
            }
        }
    }
}

MailAddress tries to be compatible with RFC2822 which obsoletes RFC822. When you read the source code of MailAddress you see that the end-dot it's accepted just for compatibility with some e-mail clients. Validating e-mail address with regex is not the right thing to do (see RFC2822), the best way is to implement a parser, what MailAddress did.

see DotAtomReader used by MailAddressParser

Not a free solution but Cobisi's email validation library can tell whether the email valid or not within different level of accuracy (Syntax, IspSpecificSyntax, DeaDomain, Dns, DeaMailExchanger, Smtp, Mailbox, CatchAll)

var engine = new VerificationEngine();
var result = engine.Run("john@example.com",
                        VerificationLevel.Mailbox).Result;

if (result.LastStatus == VerificationStatus.Success)
{
    // TODO: Show a message box with the great news
}

Disclaimer: I am not related to the company or the project.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top