Sunday, June 17, 2007

ASP.NET Custom Validator for a Comma Separated List of Email Addresses

In your ASPX page:

<asp:CustomValidator ID="txtToCustom" runat="server" ControlToValidate="txtTo"
Display="Dynamic" ErrorMessage="One of the &quot;To:&quot; email
addresses you provided is not in the proper format or is not separated by a comma."
OnServerValidate="txtToCustom_ServerValidate">*</asp:CustomValidator>

In your code beside page:

protected void txtToCustom_ServerValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = ValidateToAddresses(args.Value);
}

protected bool ValidateToAddresses(string addresses)
{
string[] myAddresses = Tokenize(addresses);
foreach (string address in myAddresses)
{
if (!IsEmail(address.Trim())) return false; // If it's not a valid address, return false.
}
return true; // If none of the addresses returned false, return true.
}

protected bool IsEmail(string address)
{
/* This regular expression is provided by the .NET Framework and is the same
* as the one used to check the from address. If that changes for any reason
* this should be updated to match. */
Regex emailRegEx = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
RegexOptions.IgnoreCase);
if (emailRegEx.IsMatch(address)) return true;
return false;
}

protected string[] Tokenize(string addresses)
{
/* This is pulled out as a separate function because I expect it to mature
* and change over time, and it will probably to move into a class library
* at some point. */
Regex separatorRegEx = new Regex(",");
return separatorRegEx.Split(addresses);
}

There is at least one very big assumption here: the domains provided by the user are correct. If you'd like to check these, there is a bit of code at http://www.codeproject.com/aspnet/Valid_Email_Addresses.asp that offers an approach.

Also, to do this, you need some sort of approach to string tokenization. Unlike Java, C# does not have any helper classes for this. There are basic approaches to this problem at http://en.csharp-online.net/CSharp_Regular_Expression_Recipes%E2%80%94A_Better_Tokenizer and http://www.dotnetwatch.com/page229.aspx.

4 comments:

Berty said...

Mattio,

I have implemented something similar, thanks for the ideas - but there is a case that got past the validator:

When you enter 2 addresses with a enter after the first one (no comma) in a text box it seems to be parsed as valid. It grabs the whole 2 addresses as one item in the array and does not fail on the validation expression.

eg:
"AustralianPokerLeague@poker.com
AmateurPokerLeague@poker.com"

Any tips on how to handle this please?

Berty said...

One more thing to note:

If you use a core .NET Validator control with that same regex expression it DOES catch this error:
"AustralianPokerLeague@pokerdiy.comAmateurPokerLeague@pokerdiy.com"
ie. two @

BUT with the Regex Match check it does not. How do you tell it to only be valid if there is one occurrence?

Thanks

Mattio Valentino said...

If you can't get past this issue, try using StackOverflow.com instead.

Berty said...

Thanks - they posted the answer:
http://stackoverflow.com/questions/1598349/problem-with-asp-net-custom-validator-for-a-comma-separated-list-of-email-address