2015-07-20 5 views
0

У меня есть следующий класс, присущего от ObservableCollection:Validate перед добавлением в коллекцию

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; 
     } 

    } 

Моего вопроса, прежде, чем будет добавлен элемент, как я могу проверять достоверность предмета? Я проверю, будет ли почта в правильном формате.

+0

ли строительство объекта 'MailAddress' сделать эту проверку? –

ответ

0

Вы можете проверить с регулярным выражением:

Regex emailRegex = new Regex(@"^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$"); 
if (emailRegex.IsMatch(e.Address) { 
    //valid eMail address 
} 
+1

Нет. Вы не можете. Единственное правильное регулярное выражение для проверки действительных адресов электронной почты находится здесь: http://ex-parrot.com/~pdw/Mail-RFC822-Address.html. Кроме того, прочтите следующее: http://davidcel.is/posts/stop-validating-email-addresses-with-regex/ –

2

Есть много потоков здесь и на других форумах о проблемах с проверкой электронной почты. Общий консенсус заключается в следующем: нет. Особенно не используйте регулярные выражения для этого.

Один из действительных способов - отправить электронную почту на адрес и проверить, выполнено ли это.

С другой стороны, ваши комментарии к коду уже дают подсказку об исключении исключения. Если изменить код следующим образом, вы можете добавлять только адреса:

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); 
      } 
     } 
} 

Это создает список недопустимых адресов и добавляет действительные адреса в вашей коллекции.

+0

Почему мы не должны использовать Regex для проверки электронной почты? – ivamax9

+0

Обратите внимание, что использование try/catch для управления программным потоком - это всегда плохая практика. Он медленный и предназначен для обработки исключений, в то время как недостающая проверка не является исключением, а недостающим кодом. – LInsoDeTeh

+0

@Chase Потому что практически невозможно создать регулярное выражение, которое проверяет все RFC-совместимые адреса электронной почты. –

0

Вы должны создать новую версию Add, SetItem и 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._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$"); 
    private bool IsValidEmailAddress(string address) { 
     return !string.IsNullOrWhiteSpace(address) && EmailValidatorRegex.IsMatch(address); 
    } 
} 

Примечание 1: Использованный Regex пришли из @LInsoDeTeh 's answer

Примечание 2: Вы можете использовать параметр при условии throwOnInvalidEmailAddress, чтобы решить, что делать с недействительными адресами, например игнорировать их, выбросить исключение, ...

0

Как сделать это как there. И затем использовать его в конструкторе:

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; 
    }  
} 
Смежные вопросы