2 Stimmen

Welches ist das richtige Entwurfsmuster, um die E-Mail-Validierung für jeden Anbieter zu implementieren?

Ich muss E-Mails durch mehrere Validierungsprogramme prüfen. Ich habe Klasse( EmailValidator ), die eine Liste von Prüfern( RegexValidator , MXValidator ...) und validiert E-Mails durch diese Validatoren. RegexValidator hat zum Beispiel für jeden Anbieter eigene Validatoren. Wenn es erkennt, dass es sich um gmail und prüft, ob es mit einem bestimmten Muster übereinstimmt, falls ja mygmail also prüft es, ob es mit dem Muster von mygmail übereinstimmt, andernfalls gibt es true zurück. MXValidator wird etwas anderes validiert.

Was ist das richtige Entwurfsmuster, um dies zu implementieren?

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

5voto

Aliostad Punkte 78595

Kette der Verantwortung.

Sobald ein Validator ein ungültiges Muster findet, wird false zurückgegeben. Sie übergeben ein bestellt Liste der Prüfer.

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

Angenommen,

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

UPDATE

Ich sehe dies als einen weiteren Validator:

public class EmailDomainValidator : IValidator
{

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

   ...
}

0voto

Thomas Wickham Punkte 180

Das ist zwar keine direkte Antwort auf Ihr Problem, aber ich glaube, dass Sie es falsch machen.

En real Die Validierung einer E-Mail basiert nicht auf ihrer String-Darstellung, sondern auf einem einfachen Test. Sie senden eine E-Mail, jemand antwortet, die E-Mail ist gut. Andernfalls ist sie schlecht.

Es gibt unendlich viele gültige E-Mail-Adressen, die in der realen Welt nicht gültig sind, weil sie nicht mit einem Postfach verbunden sind.

Vielleicht sind Sie sich dessen bereits bewusst und es ist Ihr Job, diese Sache zu tun, aber wenn nicht, schlage ich Ihnen vor, eine wirklich einfache und freizügige Regex wie zu machen:

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

Wich zeigt Ihnen nur den Teil nach dem @ an und enthält eine Menge falsch positiver Ergebnisse, die Sie leicht testen können.


Was die Verkettung der Validatoren betrifft, werde ich eine List<Func<string,bool>> die alle Tests enthält und diese in einer foreach-Schleife aufruft, wobei im Falle von false eine Ausnahme ausgelöst und abgefangen wird.

EDIT: in der Tat, die LINQ-Methode mit einem Lambda ist weit besser. Das Auslösen einer Ausnahme ist teuer.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X