Code C # pour valider l'adresse e-mail


462

Quel est le code le plus élégant pour valider qu'une chaîne est une adresse e-mail valide?



9
Jetez un œil à l'article de Phil Haack: " Je savais comment valider une adresse e-mail jusqu'à ce que je
lise la

il existe de nombreuses autres validations importantes, pas seulement la chaîne, il est préférable de vérifier si l'e-mail existe sur ce serveur smtp ou si l'utilisateur entre un e-mail .. etc. ou d'utiliser une API qui s'en occupera pour que vous soyez sûr que l'e-mail est correct comme ver-email.com
Amr Magdy


vous pouvez utiliser la bibliothèque github.com/jstedfast/EmailValidation .
Mohammad Reza Sadreddini

Réponses:


784

Et ça?

bool IsValidEmail(string email)
{
    try {
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch {
        return false;
    }
}

Pour clarifier, la question demande si une chaîne particulière est une représentation valide d'une adresse de messagerie, et non si une adresse de messagerie est une destination valide pour envoyer un message. Pour cela, le seul vrai moyen est d'envoyer un message pour confirmer.

Notez que les adresses e-mail sont plus indulgentes que vous ne le pensez. Ce sont tous des formulaires parfaitement valables:

  • roue dentée
  • "roue dentée l'orange" @ example.com
  • 123@$.xyz

Pour la plupart des cas d'utilisation, un faux "invalide" est bien pire pour vos utilisateurs et l'épreuve du temps qu'un faux "valide". Voici un article qui était la réponse acceptée à cette question (cette réponse a depuis été supprimée). Il contient beaucoup plus de détails et quelques autres idées sur la façon de résoudre le problème.

Fournir des contrôles d'intégrité est toujours une bonne idée pour l'expérience utilisateur. En supposant que l'adresse e-mail est valide, vous pouvez rechercher des domaines de premier niveau connus, rechercher un enregistrement MX dans le domaine, rechercher des erreurs d'orthographe à partir de noms de domaine communs (gmail.cmo), etc. Ensuite, présenter un avertissement donnant à l'utilisateur une chance de dire "oui, mon serveur de messagerie autorise vraiment 🌮🍳🎁 comme adresse e-mail."


Quant à l'utilisation de la gestion des exceptions pour la logique métier, je suis d'accord que c'est une chose à éviter. Mais c'est l'un de ces cas où la commodité et la clarté peuvent l'emporter sur le dogme.

De plus, si vous faites autre chose avec l'adresse e-mail, cela impliquera probablement de la transformer en MailAddress. Même si vous n'utilisez pas cette fonction exacte, vous voudrez probablement utiliser le même modèle. Vous pouvez également rechercher des types d'échecs spécifiques en interceptant différentes exceptions : format nul, vide ou non valide.


Selon le commentaire de Stuart, cela compare l'adresse finale avec la chaîne d'origine au lieu de toujours retourner true. MailAddress essaie d'analyser une chaîne avec des espaces dans les parties "Nom d'affichage" et "Adresse", de sorte que la version d'origine renvoyait des faux positifs.


--- Lectures complémentaires ---

Documentation pour System.Net.Mail.MailAddress

Explication de ce qui constitue une adresse e-mail valide


23
En fait, ce n'est pas incorrect. a @ a est une adresse e-mail valide. Voir haacked.com/archive/2007/08/21/… En fait, cette méthode renvoie des résultats incorrects si vous utilisez une adresse avec des guillemets.
Cogwheel

53
+1: C'est la meilleure réponse si vous utilisez les System.Net.Mailclasses pour envoyer du courrier, ce que vous êtes probablement si vous utilisez .NET. Nous avons décidé d'utiliser ce type de validation simplement parce qu'il est inutile d'accepter des adresses e-mail - même valides - auxquelles nous ne pouvons pas envoyer de courrier.
Greg Beech

24
Je ne le recommande pas. Cela revient vrai:IsValidEmail("this is not valid@email$com");
Kakashi

15
Beaucoup de problèmes semblent être dus au fait que MailAddress essaie également d'analyser le DisplayName, donc "single space@domain.com" analyse à DisplayName "single" et à l'adresse "space@domain.com". Une solution pour cela est de: retourner (addr.Address == email);
Stuart

18
J'aime ça; Je ne reçois pas la contrainte d'être plus restrictive que la spécification réelle. Les faux négatifs sont bien pires que les faux positifs ("que voulez-vous dire que mon e-mail est invalide? ")
Casey

242

C'est une vieille question, mais toutes les réponses que j'ai trouvées sur SO, y compris les plus récentes, reçoivent une réponse similaire à celle-ci. Cependant, dans .Net 4.5 / MVC 4, vous pouvez ajouter une validation d'adresse e-mail à un formulaire en ajoutant l'annotation [EmailAddress] de System.ComponentModel.DataAnnotations, donc je me demandais pourquoi je ne pouvais pas simplement utiliser la fonctionnalité intégrée de. Net en général.

Cela semble fonctionner et me semble assez élégant:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var foo = new EmailAddressAttribute();
        bool bar;
        bar = foo.IsValid("someone@somewhere.com");         //true
        bar = foo.IsValid("someone@somewhere.co.uk");       //true
        bar = foo.IsValid("someone+tag@somewhere.net");     //true
        bar = foo.IsValid("futureTLD@somewhere.fooo");      //true

        bar = foo.IsValid("fdsa");                          //false
        bar = foo.IsValid("fdsa@");                         //false
        bar = foo.IsValid("fdsa@fdsa");                     //false
        bar = foo.IsValid("fdsa@fdsa.");                    //false

        //one-liner
        if (new EmailAddressAttribute().IsValid("someone@somewhere.com"))
            bar = true;    
    }
}

4
Cool, bien qu'il soit décevant que MS ne puisse pas accepter cela avec sa propre documentation . Cela rejette js@proseware.com9
Casey

13
Notez que cela EmailAddressAttributeest moins permissif que System.Net.Mail.MailAddress- par exemple, MailAddressaccepte une adresse pour un TLD. Juste quelque chose à garder à l'esprit si vous devez être aussi permissif que possible.
Aaroninus

5
@Cogwheel: si la réponse se trouve quelque part dans les commentaires, elle devrait probablement être ajoutée au corps principal de la réponse.
hofnarwillie

6
@hofnarwillie: c'est dans le corps principal, mais les commentaires sont élaborés. Si votre objectif est de ne pas irriter vos utilisateurs, votre validation ne devrait pas être plus restrictive que la spécification. La seule façon de vraiment vérifier si un e-mail est valide est d'envoyer un message de test.
Cogwheel

4
Veuillez noter que les foo.IsValid(null);retours true.
urig

62

J'utilise cette méthode de doublure unique qui fait le travail pour moi-

using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
    return new EmailAddressAttribute().IsValid(source);
}

D'après les commentaires, cela "échouera" si source(l'adresse e-mail) est nulle.

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);

1
Cela ne fonctionne pas pour moi; J'obtiens, "'Les annotations de données' n'existent pas ... vous manque une référence d'assembly?" Quelle référence dois-je ajouter?
B. Clay Shannon

Cela retournera vrai si la source est nulle. Voir msdn.microsoft.com/en-us/library/hh192424 "true si la valeur spécifiée est valide ou null; sinon, false."
jao

2
Une meilleure version:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

7
Ou encore mieux:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander

1
Je ne pense pas que cette méthode d'extension devrait retourner silencieusement falsepour les chaînes nulles. Voilà pourquoi je propose la (encore mieux mieux) ++ version: public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Je vais maintenant aller trouver l'Église réformée des versionnistes encore meilleurs et meilleurs.
Marc.2377

41

.net 4.5 a ajouté System.ComponentModel.DataAnnotations.EmailAddressAttribute

Vous pouvez parcourir la source de EmailAddressAttribute , c'est le Regex qu'il utilise en interne:

const string pattern = @"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$";

2
Malheureusement, EmaillAddressAttribute autorise Ñ qui n'est pas un caractère valide pour le courrier électronique
BZ

16
@BZ Oui, c'est ça. Pourquoi pensez-vous que ce n'est pas le cas?
Casey

@Chad Grant: Il s'agit d'une version C #. Pouvez-vous s'il vous plaît fournir un VB.Net. Parce que cela échappera aux caractères tels que \\ à \ ou vous pouvez en fournir une chaîne textuellement.
Nikhil Agrawal

3
Cela fonctionne, mais n'oubliez pas RegexOptions.IgnoreCasecar ce modèle n'autorise pas explicitement les majuscules!
Chris

1
Notez que Regex est très délibéré: "Cet attribut fournit une validation de messagerie côté serveur équivalente à jquery validate, et partage donc la même expression régulière".
Ohad Schneider

38

J'ai pris la réponse de Phil de # 1 et créé cette classe. Appelez ça comme ceci:bool isValid = Validator.EmailIsValid(emailString);

Voici la classe:

using System.Text.RegularExpressions;

public static class Validator
{

    static Regex ValidEmailRegex = CreateValidEmailRegex();

    /// <summary>
    /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx
    /// </summary>
    /// <returns></returns>
    private static Regex CreateValidEmailRegex()
    {
        string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

        return new Regex(validEmailPattern, RegexOptions.IgnoreCase);
    }

    internal static bool EmailIsValid(string emailAddress)
    {
        bool isValid = ValidEmailRegex.IsMatch(emailAddress);

        return isValid;
    }
}

5
Juste un petit, mais j'utiliserais: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc

C'est juste de l'horreur :)
Alexandru Dicu

31

Personnellement, je dirais que vous devez simplement vous assurer qu'il y a un symbole @, éventuellement avec un. personnage. Il existe de nombreuses expressions rationnelles que vous pourriez utiliser avec une exactitude variable, mais je pense que la plupart d'entre elles omettent des adresses e-mail valides ou laissent passer des adresses invalides. Si les gens veulent mettre une fausse adresse e-mail, ils en mettront une fausse. Si vous devez vérifier que l'adresse e-mail est légitime et que la personne contrôle cette adresse e-mail, vous devrez lui envoyer un e-mail avec un lien codé spécial afin qu'elle puisse vérifier qu'il s'agit bien d'une véritable adresse.


6
Personnellement, je pense que vous devriez faire un peu plus de validation que cela. Quelqu'un est obligé d'essayer l'adresse e-mail de Bobby Table ou pire.
Luke Quinane

31
Quel est le problème avec l'adresse e-mail de Bobby Table si vous utilisez des déclarations préparées. Nous parlons d'adresses e-mail valides, pas d'autres choses qui n'ont rien à voir avec ce qui constitue une adresse e-mail valide, comme comment faire correctement des requêtes SQL afin de ne pas avoir de problèmes d'injection SQL.
Kibbee

Je suppose que vous ne savez pas ce que quelqu'un y mettra, mais une personne malveillante sait que la valeur peut éventuellement être introduite dans votre système de messagerie. Je préférerais juste approfondir la défense et être un peu plus strict.
Luke Quinane

10
C'est pour le système de messagerie qu'il faut s'inquiéter. Je ne voudrais pas rejeter les adresses e-mail parfaitement valides simplement parce que cela pourrait être un problème de sécurité avec un autre système. Si tout ce dont votre serveur de messagerie a besoin est une adresse e-mail mal formée pour causer des problèmes de sécurité, vous devriez probablement passer à un autre serveur.
Kibbee

4
La défense en profondeur ne fonctionne que si chaque niveau de votre oignon de sécurité n'est pas pourri. Une couche pourrie signifie que vous gâtez l'oignon entier. Rejeter "foo@example.com.au" parce que vous voulez vous défendre contre les vulnérabilités dans l'encodage µ-law de Sun n'a pas de sens, n'est-ce pas? Ne riez pas, ça m'est arrivé. La raison pour laquelle je commente ici est que Medicare Australia n'autorise pas les adresses ".au", seulement ".com". Lisez également Mark Swanson, "Comment ne pas valider les e-mails", mdswanson.com/blog/2013/10/14/…
ManicDee

17

Je pense que la meilleure façon est la suivante:

    public static bool EmailIsValid(string email)
    {
        string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

        if (Regex.IsMatch(email, expression))
        {
            if (Regex.Replace(email, expression, string.Empty).Length == 0)
            {
                return true;
            }
        }
        return false;
    }

Vous pouvez avoir cette fonction statique dans une classe générale.


Cette réponse n'accepte pas une adresse avec un TLD dans la partie domaine.
Simone

15

Code court et précis

string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
   //use code here 
}

public static bool IsValidEmail(this string email)
{
  string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";    
  var regex = new Regex(pattern, RegexOptions.IgnoreCase);    
  return regex.IsMatch(email);
}

2
Merci pour la solution
Jack Gajanan

J'ai dû changer le bool statique public IsValidEmail (cette chaîne e-mail) en bool statique public IsValidEmail (chaîne e-mail) pour éviter cela: stackoverflow.com/questions/10412233/…
Goner Doug

@Goner Doug, cette fonctionnalité fonctionnera comme ceci. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
le "CECI" devait être supprimé pour éviter de causer des problèmes de compilation lors de l'ajout à mon formulaire.
Goner Doug

@Goner Doug, Sa fonctionnalité fonctionnera comme ça. email de chaîne = "abc@xyz.com"; if (email.IsValidEmail ()) {return false; } else {return true;}
Naveen

14

La manière la plus élégante est d'utiliser les méthodes intégrées de .Net.

Ces méthodes:

  • Sont essayés et testés. Ces méthodes sont utilisées dans mes propres projets professionnels.

  • Utilisez des expressions régulières en interne, fiables et rapides.

  • Fabriqué par Microsoft pour C #. Inutile de réinventer la roue.

  • Renvoie un résultat booléen. Vrai signifie que l'e-mail est valide.

Pour les utilisateurs de .Net 4.5 et supérieur

Ajoutez cette référence à votre projet:

System.ComponentModel.DataAnnotations

Vous pouvez maintenant utiliser le code suivant:

(new EmailAddressAttribute().IsValid("youremailhere@test.test"));

Exemple d'utilisation

Voici quelques méthodes pour déclarer:

protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
    List<string> MethodResult = null;

    try
    {
        List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();

        List<string> RecipientsCleaned = new List<string>();

        foreach (string Recipient in RecipientsCleaned)
        {
            if (!String.IsNullOrWhiteSpace(Recipient))
            {
                RecipientsNoBlanks.Add(Recipient);

            }

        }

        MethodResult = RecipientsNoBlanks;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();
    }

    return MethodResult;

}


public static bool IsValidEmailAddresses(List<string> recipients)
{
    List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);

    return InvalidAddresses != null && InvalidAddresses.Count == 0;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch//(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

... et un code les démontrant en action:

List<string> Recipients = GetRecipients();

bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);

if (IsValidEmailAddresses)
{
    //Emails are valid. Your code here

}
else
{
    StringBuilder sb = new StringBuilder();

    sb.Append("The following addresses are invalid:");

    List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);

    foreach (string InvalidEmail in InvalidEmails)
    {
        sb.Append("\n" + InvalidEmail);

    }

    MessageBox.Show(sb.ToString());

}

De plus, cet exemple:

  • S'étend au-delà de la spécification, car une seule chaîne est utilisée pour contenir 0, une ou plusieurs adresses électroniques séparées par un point-virgule ; .
  • Montre clairement comment utiliser la méthode IsValid de l'objet EmailAddressAttribute.

Alternative, pour les utilisateurs d'une version de .Net inférieure à 4,5

Pour les situations où .Net 4.5 n'est pas disponible, j'utilise la solution suivante:

Plus précisément, j'utilise:

public static bool IsValidEmailAddress(string emailAddress)
{
    bool MethodResult = false;

    try
    {
        MailAddress m = new MailAddress(emailAddress);

        MethodResult = m.Address == emailAddress;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
    List<string> MethodResult = null;

    try
    {
        List<string> InvalidEmailAddresses = new List<string>();

        foreach (string Recipient in recipients)
        {
            if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
            {
                InvalidEmailAddresses.Add(Recipient);

            }

        }

        MethodResult = InvalidEmailAddresses;

    }
    catch //(Exception ex)
    {
        //ex.HandleException();

    }

    return MethodResult;

}

1
@ThomasAyoub Je n'ai pas vu de réponse EmailAddressAttribute, et aucune réponse qui utilise le nouveau MailAddress () avec une vérification de l'entrée == .Address donc je pense que c'est assez utile. Sans lecture des commentaires, la réponse acceptée est assez fausse. nouvelle MailAddress ("Foobar Some@thing.com") le prouve.
Jan

@Jan fwiw, Manik a battu Knickerless au bout d'un EmailAddressAttributepeu moins de quatre mois, bien que celui-ci ait bien compris le nullproblème.
ruffin

7

Pour être honnête, dans le code de production, le mieux que je fais est de rechercher un @symbole.

Je ne suis jamais en mesure de valider complètement les e-mails. Vous savez comment je vois si c'était vraiment valable? Si elle a été envoyée. Si ce n'est pas le cas, c'est mauvais, si c'est le cas, la vie est belle. C'est tout ce que je dois savoir.


6

Je trouve que cette expression régulière est un bon compromis entre la vérification de quelque chose de plus que la simple marque @ et l'acceptation de cas étranges:

^[^@\s]+@[^@\s]+(\.[^@\s]+)+$

Cela vous fera au moins mettre quelque chose autour de la marque @ et mettre au moins un domaine d'apparence normale.


J'ai trouvé le même regex;) Il autorise cependant les characheurs invalides
Stefan

Cette réponse n'accepte pas un TLD dans la partie domaine.
Simone

@Simone, personne n'a probablement d'adresse e-mail avec le TLD dans la partie domaine, mais dans la pratique: serverfault.com/a/721929/167961 note dans les commentaires qu'il peut être interdit ces jours-ci
Matthew Lock

@MatthewLock Serait-ce une adresse intranet? Comme bob@companyinternal?
Simone

@Simone est-ce que quelqu'un dans la vraie vie utilise réellement ce schéma?
Matthew Lock

4

La validation des adresses e-mail n'est pas aussi simple que cela puisse paraître. Il est en fait théoriquement impossible de valider complètement une adresse e-mail en utilisant simplement une expression régulière.

Consultez mon blog à ce sujet pour une discussion sur le sujet et une implémentation F # à l'aide de FParsec. [/ shameless_plug]


1
J'ai aimé votre liste d'approches alternatives; très intéressant.
Luke Quinane

1
Article intéressant. Mais sérieusement, qui met des commentaires, et ceux qui sont imbriqués, dans les adresses e-mail?
Matthew Lock

3
@matthew Je ne sais pas pourquoi l'IETF a même permis cela, mais c'est possible , donc une validation approfondie doit en tenir compte.
Mauricio Scheffer

4

Voici ma réponse - la solution de Phil échoue pour les domaines à lettre unique comme "quelqu'un@q.com". Croyez-le ou non, c'est utilisé =) (va à centurylink, par exemple).

La réponse de Phil ne fonctionnera également qu'avec la norme PCRE ... donc C # le prendra, mais javascript va exploser. C'est trop complexe pour javascript. Vous ne pouvez donc pas utiliser la solution de Phil pour les attributs de validation mvc.

Voici mon regex. Cela fonctionnera parfaitement avec les attributs de validation MVC.
- Tout avant le @ est simplifié, de sorte qu'au moins javascript fonctionne. Je suis d'accord pour relaxer la validation ici tant que le serveur d'échange ne me donne pas de 5.1.3. - Tout après la @ est la solution de Phil modifiée pour les domaines à lettre unique.

public const string EmailPattern =
        @"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\@[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$";

Pour les personnes suggérant d'utiliser system.net.mail MailMessage (), cette chose est FAIBLE à flexible. Bien sûr, C # acceptera l'e-mail, mais le serveur d'échange bombardera avec une erreur d'exécution 5.1.3 dès que vous essayez d'envoyer l'e-mail.


cela semble être la meilleure réponse la plus réfléchie / raisonnable / du monde réel, merci Ralph!
Fattie

c'est la meilleure réponse à ce jour! Je ne peux pas croire qu'une mauvaise solution qui accepte basket@ballcomme adresse e-mail valide ait obtenu la bonne réponse ainsi que tous ces votes positifs. Merci quand même!
catastrophekid

Merci, c'est la meilleure solution et devrait être acceptée.
Bat_Programmer

3

Si vous voulez vraiment et je veux vraiment savoir si une adresse e-mail est valide ... demandez à l'échangeur de courrier de le prouver, aucune expression régulière n'est nécessaire. Je peux fournir le code sur demande.

Les étapes générales sont les suivantes: 1. l'adresse e-mail comporte-t-elle une partie de nom de domaine? (index de @> 0) 2. à l'aide d'une requête DNS, demandez si le domaine dispose d'un échangeur de messagerie 3. ouvrez la connexion TCP à l'échangeur de messagerie 4. à l'aide du protocole smtp, ouvrez un message au serveur en utilisant l'adresse e-mail comme récepteur 5. analyser la réponse du serveur. 6. quittez le message si vous êtes arrivé jusqu'ici, tout va bien.

C'est comme vous pouvez l'imaginer, très coûteux en temps et repose sur smtp, mais cela fonctionne.


Avez-vous créé des faux, des talons et / ou des maquettes pour ces interfaces?
Mark A

1
Ça ne marchera pas. Le protocole smtp pour vérifier une adresse e-mail est LONGTEMPS obsolète / non utilisé. Il est considéré comme une mauvaise pratique d'activer cela sur les serveurs de messagerie car les spammeurs utilisent cette fonctionnalité.
Chad Grant

Je garderai votre suggestion au point 2. Bien plus à l'épreuve du temps que la vérification d'un modèle de nom de domaine connu.
Simone

Nitpicking, mais définir "a un échangeur de courrier" ? Si aucun enregistrement MX n'existe, SMTP doit revenir à l'enregistrement A / AAAA, conformément à RFC2821 / 5321. Si un enregistrement MX existe, cela peut ne pas indiquer qu'un échangeur de messagerie existe (RFC7505). Vraiment, la seule façon est de leur envoyer un mail avec un lien d'appel à l'action, et d'attendre qu'ils répondent ...
jimbobmcgee

2

D'une manière générale, une expression régulière pour valider les adresses e-mail n'est pas une chose facile à trouver; au moment d'écrire ces lignes, la syntaxe d'une adresse e-mail doit suivre un nombre relativement élevé de normes et leur mise en œuvre au sein d'une expression régulière est pratiquement impossible!

Je vous suggère fortement d'essayer notre EmailVerify.NET , une bibliothèque .NET mature qui peut valider les adresses e-mail après tout les normes IETF actuelles (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 et RFC 5322) , teste les enregistrements DNS associés, vérifie si les boîtes aux lettres cibles peuvent accepter des messages et peuvent même dire si une adresse donnée est jetable ou non.

Avertissement: je suis le développeur principal de ce composant.


Impressionnant! "Ensuite, il essaie de contacter l'échangeur de messagerie responsable de l'adresse e-mail donnée et commence une fausse boîte de dialogue SMTP avec ce serveur, émulant un vrai serveur de messagerie. De cette façon, il garantit que le serveur peut gérer les e-mails pour l'adresse. De nombreux serveurs SMTP en fait redonner des réponses fausses positives comme protection contre les spammeurs: pour surmonter ce problème, EmailVerify pour .NET tente enfin d'interroger l'échangeur de messagerie cible plusieurs fois avec différentes adresses fabriquées. "
Matthew Lock

Merci, @MatthewLock;)
Efran Cobisi

Sympa, mais je ne vois que des éditions payantes. Avez-vous des plans pour une édition communautaire / OpenSource?
Ohad Schneider

1
@OhadSchneider Oui: nous proposons une version gratuite de notre technologie de validation des e-mails via Verifalia, notre service de vérification des e-mails SaaS . Verifalia est livré avec des SDK gratuits et open-source pour les principales plates-formes de développement logiciel, y compris .NET .
Efran Cobisi

2
For the simple email like goerge@xxx.com, below code is sufficient. 

 public static bool ValidateEmail(string email)
        {
            System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
            System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email);
            return emailMatch.Success;
        }

Il ne sera pas possible de valider a@b.info comme adresse e-mail valide.
Ray Cheng

2

Si vous utilisez FluentValidation, vous pouvez écrire quelque chose d'aussi simple que ceci:

public cass User
{
    public string Email { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address.");
    }
}

// Validates an user. 
var validationResult = new UserValidator().Validate(new User { Email = "açflkdj" });

// This will return false, since the user email is not valid.
bool userIsValid = validationResult.IsValid;

2

une petite modification de la réponse @Cogwheel

public static bool IsValidEmail(this string email)
{
  // skip the exception & return early if possible
  if (email.IndexOf("@") <= 0) return false;

  try
  {
    var address = new MailAddress(email);
    return address.Address == email;
  }
  catch
  {
    return false;
  }
}

Cela ne semble pas aider ... Console.WriteLine(MailAddress("asdf@asdf.").Address);affiche "asdf @ asdf.", Ce qui n'est pas valide.
Langdon

.net semble avoir sa propre définition de valide. discussion
waitforit

2

Il y a beaucoup de réponses solides ici. Cependant, je recommande que nous prenions du recul. @Cogwheel répond à la question https://stackoverflow.com/a/1374644/388267 . Néanmoins, cela pourrait être coûteux dans un scénario de validation en masse, si une grande partie de l'adresse e-mail en cours de validation n'est pas valide. Je suggère que nous employions un peu de logique avant d'entrer dans son bloc try-catch. Je sais que le code suivant pourrait être écrit à l'aide de RegEx mais cela pourrait être coûteux à comprendre pour les nouveaux développeurs. C'est ma valeur de deux cents:

    public static bool IsEmail(this string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return false;

        // MUST CONTAIN ONE AND ONLY ONE @
        var atCount = input.Count(c => c == '@');
        if (atCount != 1) return false;

        // MUST CONTAIN PERIOD
        if (!input.Contains(".")) return false;

        // @ MUST OCCUR BEFORE LAST PERIOD
        var indexOfAt = input.IndexOf("@", StringComparison.Ordinal);
        var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
        var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
        if (!atBeforeLastPeriod) return false;

        // CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267 
        try
        {
            var addr = new System.Net.Mail.MailAddress(input);
            return addr.Address == input;
        }
        catch
        {
            return false;
        }
    }

2

La réponse la plus votée de @Cogwheel est la meilleure réponse, mais j'ai essayé d'implémenter trim()une méthode de chaîne afin de réduire tous les espaces blancs de l'utilisateur du début à la fin de la chaîne. Vérifiez le code ci-dessous pour un exemple complet-

bool IsValidEmail(string email)
{
    try
    {
        email = email.Trim();
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == email;
    }
    catch
    {
        return false;
    }
}

Le risque est que vous validiez une adresse e-mail différente de la source, ce qui vous laisse penser que vous pouvez envoyer un e-mail à (dans ce cas) la version non tronquée de l'adresse e-mail spécifiée. Une meilleure approche serait de créer une méthode distincte SanitizeEmail(string email), en utilisant le résultat de cette méthode pour valider et envoyer l'e-mail à.
Marco de Zeeuw

1
private static bool IsValidEmail(string emailAddress)
{
    const string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
                                     + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
                                     + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress);
}

1

Vérifiez que la chaîne de courrier électronique est au bon format ou au mauvais format en System.Text.RegularExpressions:

    public static bool IsValidEmailId(string InputEmail)
    {
        Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
        Match match = regex.Match(InputEmail);
        if (match.Success)
            return true;
        else
            return false;
    }

    protected void Email_TextChanged(object sender, EventArgs e)
    {
        String UserEmail = Email.Text;
        if (IsValidEmailId(UserEmail))
        {
            Label4.Text = "This email is correct formate";
        }
        else
        {
            Label4.Text = "This email isn't correct formate";
        }
    }

1

/ Utilisation de la regex interne utilisée pour créer le "nouveau EmailAddressAttribute ();" composant dans .Net4.5 >>> using System.ComponentModel.DataAnnotations; // Pour valider une adresse e-mail ...... testé et fonctionnel.

public bool IsEmail(string email)
{
    if (String.IsNullOrEmpty(email))
    {   return false;  }
    try
    {
        Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
                "+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
                "((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
                "FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
                "(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
                "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
                "-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
                "EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
        return _regex.IsMatch(email);
    }
    catch (RegexMatchTimeoutException)
    {
        return false;
    }
}

Vous pouvez également utiliser ceci:

http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx


il dit vrai pour cet e-mail: "fulya_42_@hotmail.coö" et il jette une erreur sur mandrill api
MonsterMMORPG

1
Tout d'abord, l'e-mail est valide par exemple@example.co ou exemple@example.com .... L'e-mail contient toutes les chaînes et critères valides à l'exception du dernier caractère "ö" et vous pouvez facilement ajouter une condition simple pour valider ce caractère . Deuxièmement, je ne suis pas sûr de cette erreur d'api mandrill, vous voudrez peut-être vérifier votre méthode d'utilisation bcos J'ai utilisé cette validation sur un autre environnement / api et cela m'a fait du bien.
Aina Ademola C

1

J'ai succincté la réponse de Poyson 1 comme ceci:

public static bool IsValidEmailAddress(string candidateEmailAddr)
{
    string regexExpresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
    return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) && 
           (Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}

1

Un moyen simple d'identifier l'e-mail est valide ou non.

public static bool EmailIsValid(string email)
{
        return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}

1

Il y a un problème de culture dans l'expression régulière en C # plutôt qu'en js. Nous devons donc utiliser l'expression régulière en mode américain pour la vérification des e-mails. Si vous n'utilisez pas le mode ECMAScript, les caractères spéciaux de votre langue sont implicites en AZ avec regex.

Regex.IsMatch(email, @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9_\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", RegexOptions.ECMAScript)

1

J'ai fini par utiliser cette expression régulière, car elle valide avec succès les virgules, les commentaires, les caractères Unicode et les adresses de domaine IP (v4).

Les adresses valides seront:

"" @ example.org

(comment)test@example.org

тест@example.org

ტესტი @ example.org

test @ [192.168.1.1]

 public const string REGEX_EMAIL = @"^(((\([\w!#$%&'*+\/=?^_`{|}~-]*\))?[^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))(\([\w!#$%&'*+\/=?^_`{|}~-]*\))?@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";

1

Un simple sans utiliser Regex (que je n'aime pas pour sa mauvaise lisibilité):

bool IsValidEmail(string email)
{
    string emailTrimed = email.Trim();

    if (!string.IsNullOrEmpty(emailTrimed))
    {
        bool hasWhitespace = emailTrimed.Contains(" ");

        int indexOfAtSign = emailTrimed.LastIndexOf('@');

        if (indexOfAtSign > 0 && !hasWhitespace)
        {
            string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);

            int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');

            if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
                return true;
        }
    }

    return false;
}

Exemples:

  • IsValidEmail("@b.com") // false
  • IsValidEmail("a@.com") // false
  • IsValidEmail("a@bcom") // false
  • IsValidEmail("a.b@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("a b@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@b.c.com") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

Il est censé être simple et ne traite donc pas de rares cas comme les e-mails avec des domaines entre crochets qui contiennent des espaces (généralement autorisés), les e-mails avec des adresses IPv6, etc.


1

Voici une réponse à votre question à vérifier.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class RegexUtilities
{    
   public bool IsValidEmail(string strIn)
   {
       if (String.IsNullOrEmpty(strIn))
       {
          return false;

       }

       // Use IdnMapping class to convert Unicode domain names.

       try 
       {
          strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200));

       }
       catch (RegexMatchTimeoutException) 
       {
           return false;

       }

       if (invalid)
       {
           return false;

       }

       // Return true if strIn is in valid e-mail format.    

       try 
       {
          return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|       [-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));

       }
       catch (RegexMatchTimeoutException) 
       {
          return false;

       }

   }


   private string DomainMapper(Match match)
   {
      // IdnMapping class with default property values.

      IdnMapping idn = new IdnMapping();

      string domainName = match.Groups[2].Value;

      try 
      {
         domainName = idn.GetAscii(domainName);

      }
      catch (ArgumentException) 
      {
         invalid = true;

      }

      return match.Groups[1].Value + domainName;

   }

}

1

Sur la base de la réponse de @Cogwheel, je souhaite partager une solution modifiée qui fonctionne pour SSIS et le "composant de script":

  1. Placez le «composant de script» dans votre connexion de flux de données, puis ouvrez-le.
  2. Dans la section "Colonnes d'entrée", définissez le champ qui contient les adresses e-mail sur "ReadWrite" (dans l'exemple 'fieldName').
  3. Revenez à la section "Script" et cliquez sur "Modifier le script". Ensuite, vous devez attendre l'ouverture du code.
  4. Placez ce code dans la bonne méthode:

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        string email = Row.fieldName;
    
        try
        {
            System.Net.Mail.MailAddress addr = new System.Net.Mail.MailAddress(email);
            Row.fieldName= addr.Address.ToString();
        }
        catch
        {
            Row.fieldName = "WRONGADDRESS";
        }
    }

Ensuite, vous pouvez utiliser un fractionnement conditionnel pour filtrer tous les enregistrements non valides ou tout ce que vous voulez faire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.