2

我必须通过几个验证器来验证电子邮件。我有EmailValidator具有验证器列表(RegexValidatorMXValidator...)的类(),它通过该验证器验证电子邮件。 RegexValidator例如,每个提供者都有自己的验证器。如果它识别出这是gmail,那么它会检查它是否匹配特定的模式,如果它是mygmail,那么它会检查它是否匹配 mygmail 的模式,否则它会返回 true。 MXValidator将验证其他内容。

实现这一点的正确设计模式是什么?

public interface IValidator
{
   bool Validate(string email);
}
public class RegexValidator : IValidator
    {
        private const string EMAIL_REGEX = @"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b";
        public bool Validate(string email)
        {
            var regex = new Regex(EMAIL_REGEX);
            var isEmailFormat regex.IsMatch(email);
            if(isEmailFormat)
            {
                 //here it should recognize the provider and check if it match the provider's pattern
            }

            return true;
        }
    }
4

2 回答 2

5

责任链。

一旦一个验证器发现无效模式,就返回 false。您传递了一个有序的验证器列表。

bool ValidateEmail(string email, IEnumerable<IValidator> validators, ref errorMessage)
{
    return !validators.Any(v => !v.Validate(email, ref errorMessage);
}

假设

interface IValidator
{
    bool Validate(object value, ref errorMessage);
}

更新

我看到这是作为另一个验证器实现的:

public class EmailDomainValidator : IValidator
{

   public EmailDomainValidator(string domain)
   {
      _domain = domain;
   }

   ...
}
于 2012-05-01T12:42:05.450 回答
0

这不是您问题的直接答案,但我认为您做错了。

一封电子邮件的真正验证不是基于他的字符串表示,而是通过一个简单的测试。你发邮件,有人回复,邮件就不错了。否则很糟糕。

您有无数个在现实世界中无效的有效邮件地址,因为它们与邮箱无关。

也许您已经意识到这一点并且做这件事是您的工作,但如果不是,我建议您制作一个非常简单且宽松的正则表达式,例如:

(?<=[\w-\.@]+@)[\w-\.]+

Wich 将仅向您显示 @ 之后的部分,并且将包含许多您可以轻松测试的误报。


关于验证器的链接,我将创建一个List<Func<string,bool>>包含所有测试并在 foreach 循环中调用所有测试,在错误的情况下抛出并捕获异常。

编辑:事实上,带有 lambda 的 LINQ 方法要好得多。抛出异常是昂贵的。

于 2012-05-01T13:03:37.877 回答