views:

481

answers:

4

I want a function to test that a string is formatted like an email address.

What comes built-in with the .NET framework to do this?

This works:

Function IsValidEmailFormat(ByVal s As String) As Boolean
    Try
        Dim a As New System.Net.Mail.MailAddress(s)
    Catch
        Return False
    End Try
    Return True
End Function

But, is there a more elegant way?

+4  A: 

You should use Regular Expressions to validate email addresses.

unknown
so you can have 2 problems :)
voyager
A: 

You could use a Regex to do this.

There have been written a lot of articles about it; this came up when I searched google for 'regex to validate email address':

click

click

Frederik Gheysels
A agree with voyager. Now I'd have two problems.
Zack Peterson
These are better than the regex in the MSDN article but still fail on many edge cases.
Jeff Tucker
+3  A: 

MSDN Article: How to: Verify That Strings are in Valid E-Mail Format

This example method calls the Regex.IsMatch(String, String) method to verify that the string conforms to a regular expression pattern.

Function IsValidEmailFormat(ByVal s As String) As Boolean
    Return Regex.IsMatch(s, "^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$")
End Function
Edmundo
That seems definitive. But, I'd still prefer to find such a function built-in and squirreled away somewhere within System.Net.Mail. :(
Zack Peterson
This fails to take into account many different edge cases with email addresses, the most significant of which is a quoted local part. There are plenty of other non-alphanumeric characters which are valid as well that this regex doesn't allow for. I know it's an MSDN article but it's wrong. I re-wrote address parsing for .NET 4.0 in System.Net.Mail.MailAddress to be a lot more robust and take these things into account. See my answer below for more detail.
Jeff Tucker
+9  A: 

Don't bother with your own validation. .NET 4.0 has significantly improved validation via the MailAddress class. Just use MailAddress address = new MailAddress(input) and if it throws, it's not valid. If there is any possible interpretation of your input as an RFC 2822 compliant email address spec, it will parse it as such. The regexes above, even the MSDN article one, are wrong because they fail to take into account a display name, a quoted local part, a domain literal value for the domain, correct dot-atom specifications for the local part, the possibility that a mail address could be in angle brackets, multiple quoted-string values for the display name, escaped characters, unicode in the display name, comments, and maximum valid mail address length. I spent three weeks re-writing the mail address parser in .NET 4.0 for System.Net.Mail and trust me, it was way harder than just coming up with some regular expression since there are lots of edge-cases. The MailAddress class in .NET 4.0 beta 2 will have this improved functionality.

One more thing, the only thing you can validate is the format of the mail address. You can't ever validate that an email address is actually valid for receiving email without sending an email to that address and seeing if the server accepts it for delivery. It is impossible and while there are SMTP commands you can give to the mail server to attempt to validate it, many times these will be disabled or will return incorrect results since this is a common way for spammers to find email addresses.

Jeff Tucker
Thank you for responding. I'm glad to hear that this has gotten some attention from Microsoft! But, just to clarify, you're saying that the best practice *is* to catch an exception as I've done in the function above?
Zack Peterson
Yes, you must catch the FormatException that it throws if the address is invalid. Your code is correct.
Jeff Tucker
One last thing: System.Net.Mail has gotten all kinds of attention from Microsoft for .NET 4.0. You can see what we've improved in my post on the NCL blog: http://blogs.msdn.com/ncl/archive/2009/08/06/what-s-new-in-system-net-mail.aspx
Jeff Tucker