tags:

views:

137

answers:

5

I've noticed that if you try to send an email to an invalid address, an exception is raised:

MailAddress To=new MailAddress("invalidemailaddress","recipientname");

throws:

 "The specified string is not in the form required for an e-mail address"

This means that there must be a .Net function which is executed in MailAddress to check if the email address is valid or not. Is there a way to call this 'validate' function directly? This way I won't need to create my own IsValid function.

+2  A: 

No but you can make one:

public bool ValidateEmailAddress (string email)
{
   if (string.IsNullOrEmpty (email)) return false;

    try
    {
        MailAddress to = new MailAddress (email);

        return true;
    }
    catch (WhateverException e)
    {
        return false;
    }
}

Answering comments. I am aware this technique is regarded as a bad one and with reason. What I would like to point out is that this approach will give you 100% guarantee the .NET mailing library will be able to send to a validated address lately. The problem with Regexes (of which there are plenty) is that each one addresses one particular subset of the set of technically correct addresses as per specification. One would be narrower, the other one would be wider than the subset defined internally in .NET. If you were to use Regex validation, then in the first case your Regex would cut off a portion of the valid addresses (as seen by .NET), in the latter case the validaton will let through addresses that the .NET mailing library won't treat as invalid per its own internal validation. The one true way to make sure you valid set 100% matches the .NET set (or of any other third party library you would use) is to fall for the try/catch approach, unless of course this third party library offers some validation method already.

Developer Art
Ouch. Exception handling as flow control :(
Oded
Yep, it's bad, I know. But it's simple and it works.
Developer Art
One of those things you shouldn't do, but it never causes any problems in practice.
erikkallen
A: 

Unfortunately, there is no way to get at that functionality without reverse-engineering it or using that specific exception, sadly.

The traditional way to validate an email address has always been with regular expressions, but there are lengths you can go beyond that to validate emails even further, if you so wish:

The Forgotten Art of Email Address Validation

Programming Hero
+1  A: 

There's a good example of an email validation function on CodeProject.

Original Source Code written by Vasudevan Deepak Kumar:

public static bool isEmail(string inputEmail)
{
   inputEmail  = NulltoString(inputEmail);
   string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
         @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + 
         @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";

   Regex re = new Regex(strRegex);

   if (re.IsMatch(inputEmail))
    return (true);
   else
    return (false);
}
kdmurray
Unfortunately these Regex validation make little sense under circumstances. If you intend to send mails with the .NET mailing library you want to be sure your validation works exactly like the one in the library. Otherwise either your validation cuts off a piece of wellformed addresses or alternatively it will let through addresses that the .NET mailer can't handle. Just to keep it in mind.
Developer Art
A: 

You could write your own class:

class EmailAddress
{
  private MailAddress _email;

  public string Address
  {
    get
    {
      return _email == null ? string.Empty : _email.Address;
    }
  }

  public string DisplayName
  {
    get
    {
      return _email == null ? string.Empty : _email.DisplayName;
    }
  }

  public string Host
  {
    get
    {
      return _email == null ? string.Empty : _email.Host;
    }
  }

  public string User
  {
    get
    {
      return _email == null ? string.Empty : _email.User;
    }
  }

  public EmailAddress(string email)
  {
    try {
      _email = new MailAddress(email);
    }
    catch (Exception) {
      _email = null;
    }
  }

  public EmailAddress(string email, string displayName)
  {
    try {
      _email = new MailAddress(email, displayName);
    }
    catch (Exception) {
      _email = null;
    }
  }

  public EmailAddress(string email, string displayName, Encoding displayNameEncoding)
  {
    try {
      _email = new MailAddress(email, displayName, displayNameEncoding);
    }
    catch (Exception) {
      _email = null;
    }
  }

  public bool IsValid()
  {
    return _email == null ? false : true;
  }

  public override string ToString()
  {
    return this.Address;
  }
}

Now you use it just as MailAddress but there is now no exception when the Email address is not valid. Instead you call the IsValid method:

var email = new EmailAddress("[email protected]");
if (email.IsValid()) {
  ...
}
else {
  ...
}
Sani Huttunen
A: 

Yes, there is such a .Net function, but its functionality is unaccessible by "standard" means: MailAdress uses a private ParseAddress method, which in turn uses System.Net.Mime.MailBnfHelper. The latter is an internal class, so it's not (easily) accessible outside the framework itself.

Thus, the only way to use these functions would be to use reflection, which I strongly advise against. Since these functions are undocumented and unaccessible without reflection, their implementation might change and your code might break in future versions of the framework.

Heinzi