C# 在添加到集合之前进行验证

C# 在添加到集合之前进行验证,c#,C#,我从ObservaleCollection中获得了以下固有的类: public class Emails : ObservableCollection<Email> { public Emails() { } public Emails(IEnumerable<Email> emails) { foreach (var e in emails)

我从ObservaleCollection中获得了以下固有的类:

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

    }
公共类电子邮件:ObservableCollection
{
公开电邮()
{
}
公开电子邮件(IEnumerable电子邮件)
{
foreach(电子邮件中的var e)
{
//将引发System.FormatException:
//地址的格式不可识别。
var addr=新系统.Net.Mail.MailAddress(e.Address);
加(e);
}
}
公共IEnumerable GetAll()
{
退货项目;
}
}

我的问题是,在添加元素之前,如何验证该项?如果邮件格式正确,我将进行验证。

您可以使用正则表达式进行检查:

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

这里和其他论坛上有很多关于电子邮件验证问题的帖子。普遍的共识是:不要。尤其是不要使用正则表达式

一种有效的方法是向该地址发送电子邮件,并检查是否成功

另一方面,您的代码注释已经给出了抛出异常的提示。如果按以下方式更改代码,则只能添加有效地址:

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);
            }
        }
}
公开电子邮件(IEnumerable电子邮件)
{
列表无效=新列表();
foreach(电子邮件中的var e)
{
//将引发System.FormatException:
//地址的格式不可识别。
尝试
{
var addr=新系统.Net.Mail.MailAddress(e.Address);
加(e);
}
捕获(格式化异常)
{
//地址无效。请添加到无效地址列表
//地址
无效。添加(e);
}
}
}

这将生成一个无效地址列表,并将有效地址添加到您的集合中。

您应该创建一个新版本的
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._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$");
    private bool IsValidEmailAddress(string address) {
        return !string.IsNullOrWhiteSpace(address) && EmailValidatorRegex.IsMatch(address);
    }
}
公共类电子邮件:ObservableCollection{
公开电邮(){
}
公开电子邮件(IEnumerable电子邮件){
foreach(电子邮件中的var e){
加(e);
}
}
公共IEnumerable GetAll(){
退货项目;
}
受保护的bool插入项(int索引,电子邮件项,bool throwOnInvalidEmailAddress=false){
if(IsValidEmailAddress(项目地址)){
基本插入项(索引,项目);
返回true;
}
如果(throwOnInvalidEmailAddress)
抛出新异常(“错误的电子邮件地址!”);
返回false;
}
受保护的bool SetItem(int索引、电子邮件项、bool throwOnInvalidEmailAddress=false){
if(IsValidEmailAddress(项目地址)){
base.SetItem(索引,项);
返回true;
}
如果(throwOnInvalidEmailAddress)
抛出新异常(“错误的电子邮件地址!”);
返回false;
}
公共bool Add(电子邮件项目,bool throwOnInvalidEmailAddress=false){
if(IsValidEmailAddress(项目地址)){
基础。添加(项目);
返回true;
}
如果(throwOnInvalidEmailAddress)
抛出新异常(“错误的电子邮件地址!”);
返回false;
}
私有静态只读正则表达式EmailValidatorRegex=
新的正则表达式(^[A-Z0-9.\%+-]+[A-Z0-9.-]+\[A-Z]{2,4}$”;
私有bool IsValidEmailAddress(字符串地址){
return!string.IsNullOrWhiteSpace(地址)和&EmailValidatorRegex.IsMatch(地址);
}
}
注1:使用的
Regex
来自

注2:您可以使用提供的
throwOnInvalidEmailAddress
参数来决定如何处理无效地址,例如忽略它们,引发异常,

如何处理。 然后在构造函数中使用它:

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;
  }    
}
公共类电子邮件:ObservableCollection
{
公开电邮()
{
}
公开电子邮件(IEnumerable电子邮件)
{
foreach(电子邮件中的var e)
{
如果(IsValidEmail)(例如地址)
{
加(e);
}
}
}
公共IEnumerable GetAll()
{
退货项目;
}    
}

构造
邮件地址
对象是否会进行此验证?不。您不能。这里可以找到唯一正确的正则表达式来检查有效的电子邮件地址:。另外,请阅读以下内容:为什么我们不应该使用Regex来验证电子邮件?请注意,使用try/catch来控制程序流始终是一种不好的做法。它很慢,而且适合于处理异常,而缺少的验证不是异常,而是缺少代码。@Chase,因为几乎不可能创建一个正则表达式来检查所有符合RFC的电子邮件地址。@LInsoDeTeh可以随意提供正确的验证方法。
MailAddress
的构造函数已经进行了一些验证。它可能会在失败时生成一个异常行,因此捕获该异常是完全有效的。我不是传播来使用它进行验证的。我是说:根本不验证,但要正确处理无效地址。您提供的正则表达式不会处理所有有效的电子邮件地址,因此它不是正确的验证方法。我的意思是在添加新的em之前使用ADD方法将邮件发送到集合,然后它应该进行验证。