38

Currently, to avoid errors from being thrown up due to invalid email addresses, I do the following:

Dim mailAddress As MailAddress
Try
   mailAddress = New MailAddress("testing@invalid@email.com")
Catch ex As Exception
   'Invalid email
End Try

However, rather than depending on Try..Catch, is there a way of validating that the email address will be 100% valid for the MailAddress type?

I know there a plenty of regex functions out there for validating emails, but I'm looking for the function which the MailAddress type uses to validate its addresses.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
Curtis
  • 101,612
  • 66
  • 270
  • 352
  • Did you try using a decompiler to see what `MailAddress` uses? – Oded Aug 11 '11 at 14:45
  • 1
    @Oded: I have. It uses a large internal class called `MailBnfHelper`, which has changed substantially in .Net 4.0. I do not recommend extracting it. – SLaks Aug 11 '11 at 14:47
  • Different versions of the .Net framework uses different rules for what it supports so I'd be worried that any regex:s you create might not be future proof. The `Try Catch` would be future proof though so I agree with SLaks answer. Otherwise if you really want to write a regex, the documentation for [MailAddress](http://msdn.microsoft.com/en-us/library/system.net.mail.mailaddress.aspx) describes the rules it uses so you might be able to use that as a starting point. – Hans Olsson Aug 11 '11 at 14:48
  • @ho: You **can't** use a regex. Email addresses do not form a regular language. – SLaks Aug 11 '11 at 14:49
  • Thanks for your responses. So my code would be a recommended solution? I didn't think using `Try Catch` in this manner was good practice? – Curtis Aug 11 '11 at 14:51
  • 4
    @Curt: Usually, it's not good practice, but here, it's the best option available. – SLaks Aug 11 '11 at 14:55
  • I opened a bug report. Please up-vote: https://github.com/dotnet/corefx/issues/25295 – Jonathan Allen Nov 16 '17 at 17:51

6 Answers6

40

Unfortunately, there is no MailAddress.TryParse method.

Your code is the ideal way to validate email addresses in .Net.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 2
    I would disagree with this, I would assume use a regular expression over a try/catch block as those are generally slow. – Cromat Aug 11 '11 at 14:48
  • 4
    @Cromat: Wrong. Regexes are also slow, and any regex complex enough to _approximate_ an email address will be _very_ slow. Also, `catch` blocks are only slow if an exception is actually caught, so this won't slow anything down in the common case of a valid address. – SLaks Aug 11 '11 at 14:52
  • 2
    @Oded No they are not the fastest thing out there, however using exceptions to control application flow is never a good practice. – Cromat Aug 11 '11 at 14:52
  • 1
    @Cromat: That is true, but it is the correct thing to do here (other than asking Microsoft to add a `TryParse` method). It should be wrapped in a method that returns a boolena or a nullable `MailAddress`. – SLaks Aug 11 '11 at 14:53
  • 8
    @Cromat - Correct, one _shouldn't_ use exceptions for flow control. But one also needs to know when to make an exception to this rule (no pun intended). – Oded Aug 11 '11 at 14:54
  • http://stackoverflow.com/questions/1903356/email-validation-regular-expression/1903368#1903368 – SLaks Aug 11 '11 at 14:55
  • 1
    @Cromat Just FYI: Microsoft does provide a "recommended" Regular Expression for this task at [How to: Verify that Strings Are in Valid Email Format](https://msdn.microsoft.com/en-us/library/01escwtf.aspx). _But_, just after they explain how the RegEx works, they throw in "Instead of using a regular expression to validate an email address, you can use the System.Net.Mail.MailAddress class." :) So it seems that even MS prefers the try/catch around `MailAddress` over using even their own RegEx. – Solomon Rutzky Feb 18 '15 at 03:49
  • "Jagadedhcutebou. 143@gmail.com" Passes the try catch. – Offir Nov 08 '16 at 13:16
  • @Oded Certainly ought to be, especially with .Net's ability to pre-compile regex. Is something wrong with .Net's regex that makes it slow? – Max Barraclough Jun 22 '18 at 15:01
7

Recently the .NET API was extended with a MailAddress.TryCreate method, probably coming in future releases, which will eliminate the need for the common try-catch boilerplate: https://github.com/dotnet/runtime/commit/aea45f4e75d1cdbbfc60daae782d1cfeb700be02

  • But where is `MailAddressCollection.TryCreate()` or `TryAdd()`, the multi-address equivalent? When we had only throwing methods, one would discern single vs multiple (comma-separated) through `new MailAddress(value)` vs `new MailAddressCollection().Add(valueOrValues)`. Did they overlook a bool-returning variant of the latter? – Timo Feb 03 '22 at 12:46
  • @Timo my guess it that object creation vs collection initialization/population are two different things, hence their different approach. TryCreate would refer logically to the creation of the empty MailAddressCollection itself, and even if it would exist probably wouldn't be of much use as you wouldn't get any indication which of the provided emails is wrong (?). That is however just my two cents, the pure fact is that there is no such equivalent from what I see in the source. – seekingtheoptimal Feb 07 '22 at 19:09
5

If you need to make sure a given email address is valid according to the IETF standards - which the MailAddress class seems to follow only partially, at the time of this writing - I suggest you to take a look at EmailVerify.NET, a .NET component you can easily integrate in your solutions. It does not depend on regular expressions to perform its job but it relies on an internal finite state machine, so it is very very fast.

Disclaimer: I am the lead developer of this component.

Zsolt Botykai
  • 50,406
  • 14
  • 85
  • 110
1

Not really an answer to this question per se, but in case anyone needs it, I wrote a C# function for validating email addresses using this method.

FixEmailAddress("walter@xyz.com")

returns "walter@xyz.com"

FixEmailAddress("wa@lter@xyz.com,tom@xyz.com,asdfdsf,vsav-sdfsd@xyz.xyz")

returns "tom@xyz.com,vsav-sdfsd@xyz.xyz"

I process lists of email addresses this way because a comma separated list of emails is a valid parameter for MailAddressCollection.Add()

/// <summary>
/// Given a single email address, return the email address if it is valid, or empty string if invalid.
/// or given a comma delimited list of email addresses, return the a comma list of valid email addresses from the original list.
/// </summary>
/// <param name="emailAddess"></param>
/// <returns>Validated email address(es)</returns>  
public static string FixEmailAddress(string emailAddress)
{

   string result = "";

    emailAddress = emailAddress.Replace(";",",");
   if (emailAddress.Contains(","))
   {
       List<string> results = new List<string>();
       string[] emailAddresses = emailAddress.Split(new char[] { ',' });
       foreach (string e in emailAddresses)
       {
           string temp = FixEmailAddress(e);
           if (temp != "")
           {
               results.Add(temp);
           }
       }
       result = string.Join(",", results);
   }
   else
   {

       try
       {
           System.Net.Mail.MailAddress email = new System.Net.Mail.MailAddress(emailAddress);
           result = email.Address;
       }
       catch (Exception)
       {
           result = "";
       }

   }

   return result;

}

Walter Stabosz
  • 7,447
  • 5
  • 43
  • 75
1

MS also provide the code for a regex based email validator: https://msdn.microsoft.com/en-us/library/01escwtf%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Patrick
  • 8,175
  • 7
  • 56
  • 72
0

Some characters are valid in some service providers but the same is not in others! The SmtpClient don't know anything about the service providers. So it has to filter as least as possible. The Wikipedia is welly mentioned about the standers.

Validation of MailAddress is mentioned on the MSDN. Hence I think you can check for those validations before initializing the MailAddress.

NaveenBhat
  • 3,248
  • 4
  • 35
  • 48