Reputation: 34081
I have following class inherent from ObservableCollection:
public class Emails : ObservableCollection<Email>
{
public Emails()
{
}
public Emails(IEnumerable<Email> emails)
{
foreach (var e in emails)
{
// Will throw System.FormatException:
// address is not in a recognized format.
var addr = new System.Net.Mail.MailAddress(e.Address);
Add(e);
}
}
public IEnumerable<Email> GetAll()
{
return Items;
}
}
My question is, before an element will be added, how can I validate the item? I will validate, if the mail is in the right format.
Upvotes: 0
Views: 164
Reputation: 2629
What about to do it like there. And then use it in your constructor:
public class Emails : ObservableCollection<Email>
{
public Emails()
{
}
public Emails(IEnumerable<Email> emails)
{
foreach (var e in emails)
{
if(IsValidEmail(e.Address)
{
Add(e);
}
}
}
public IEnumerable<Email> GetAll()
{
return Items;
}
}
Upvotes: 0
Reputation: 27585
You should create a new version of Add
, SetItem
, and InsertItem
:
public class Emails : ObservableCollection<Email> {
public Emails() {
}
public Emails(IEnumerable<Email> emails) {
foreach (var e in emails) {
Add(e);
}
}
public IEnumerable<Email> GetAll() {
return Items;
}
protected bool InsertItem(int index, Email item, bool throwOnInvalidEmailAddress = false) {
if (IsValidEmailAddress(item.Address)) {
base.InsertItem(index, item);
return true;
}
if (throwOnInvalidEmailAddress)
throw new Exception("Bad email address!");
return false;
}
protected bool SetItem(int index, Email item, bool throwOnInvalidEmailAddress = false) {
if (IsValidEmailAddress(item.Address)) {
base.SetItem(index, item);
return true;
}
if (throwOnInvalidEmailAddress)
throw new Exception("Bad email address!");
return false;
}
public bool Add(Email item, bool throwOnInvalidEmailAddress = false) {
if (IsValidEmailAddress(item.Address)) {
base.Add(item);
return true;
}
if (throwOnInvalidEmailAddress)
throw new Exception("Bad email address!");
return false;
}
private static readonly Regex EmailValidatorRegex =
new Regex(@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$");
private bool IsValidEmailAddress(string address) {
return !string.IsNullOrWhiteSpace(address) && EmailValidatorRegex.IsMatch(address);
}
}
Note 1: The used Regex
came from @LInsoDeTeh 's answer
Note 2: You can use the provided throwOnInvalidEmailAddress
parameter, to decide what to do with invalid addresses e.g. ignore them, throw an exception, ...
Upvotes: 0
Reputation: 56697
There are many threads here and on other forums about the problems with email validation. The general consensus is: don't. Especially don't use regular expressions to do it.
One valid way is to send an eMail to the address and check whether that succeeds.
On the other hand your code comments already give a hint about an exception being thrown. If you change the code as follows, you can only add valid addresses:
public Emails(IEnumerable<Email> emails)
{
List<Email> invalid = new List<Email>();
foreach (var e in emails)
{
// Will throw System.FormatException:
// address is not in a recognized format.
try
{
var addr = new System.Net.Mail.MailAddress(e.Address);
Add(e);
}
catch (FormatException)
{
// The address was invalid. Add to a list of invalid
// addresses
invalid.Add(e);
}
}
}
This generates a list of invalid addresses and adds the valid addresses to your collection.
Upvotes: 2
Reputation: 1038
You can check with a regex:
Regex emailRegex = new Regex(@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$");
if (emailRegex.IsMatch(e.Address) {
//valid eMail address
}
Upvotes: 0