E-posta adresini doğrulamak için C # kodu


462

Bir dizenin geçerli bir e-posta adresi olduğunu doğrulamak için en şık kod nedir?



9
Phil Haack'in makalesine bir göz atın: " RFC'yi
Okuyana

sadece dize değil, birçok önemli doğrulama var, e-postanın bu smtp sunucusunda olup olmadığını kontrol etmek veya kullanıcının herhangi bir e-posta girip girmediğini kontrol etmek daha iyidir .. vb. ver-email.com
Amr Magdy


Yanıtlar:


784

Peki buna ne dersin?

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

Açıklığa kavuşturmak için, soru, belirli bir dizenin e-posta adresinin geçerli bir temsili olup olmadığını soruyor, bir e-posta adresinin mesaj göndermek için geçerli bir hedef olup olmadığını soruyor. Bunun için tek gerçek yol onaylamak için bir mesaj göndermektir.

E-posta adreslerinin, tahmin edebileceğinizden daha bağışlayıcı olduğunu unutmayın. Bunlar tamamen geçerli formlardır:

  • dişli @ tekerlek
  • "turuncu dişli" @ example.com
  • 123@$.xyz

Çoğu kullanım durumunda, yanlış bir "geçersiz" kullanıcılarınız ve gelecekteki yazım denetimleriniz için yanlış "geçerli" olmaktan çok daha kötüdür. İşte bu soruya kabul edilen cevap olan bir makale (bu cevap o zamandan beri silindi). Sorunun nasıl çözüleceğine dair çok daha fazla ayrıntı ve başka fikirleri var.

Sağlık kontrolleri yapmak kullanıcı deneyimi için hala iyi bir fikirdir. E-posta adresinin geçerli olduğu varsayılarak, bilinen en üst düzey alan adlarını arayabilir, bir MX kaydı için alan adını kontrol edebilir, ortak alan adlarından (gmail.cmo) yazım hataları olup olmadığını kontrol edebilirsiniz. Sonra kullanıcıya bir uyarı sunabilirsiniz. "evet, posta sunucum gerçekten 🌮🍳🎁 e-posta adresi" olarak izin veriyor.


İş mantığı için istisna işleme kullanımına gelince, bunun önlenmesi gereken bir şey olduğunu kabul ediyorum. Ancak bu, rahatlığın ve netliğin dogmaya ağır basabileceği durumlardan biridir.

Ayrıca, e-posta adresiyle başka bir şey yaparsanız, muhtemelen bir MailAddress'e dönüştürmeyi içerecektir. Bu kesin işlevi kullanmasanız bile, muhtemelen aynı kalıbı kullanmak isteyeceksiniz. Farklı istisnalar yakalayarak belirli hata türlerini de kontrol edebilirsiniz : boş, boş veya geçersiz biçim.


Stuart'ın yorumuna göre, bu, son adresi her zaman true döndürmek yerine orijinal dize ile karşılaştırır. MailAddress, boşlukları olan bir dizeyi "Görünen Ad" ve "Adres" bölümlerine ayrıştırmaya çalışır, böylece orijinal sürüm yanlış pozitifler döndürüyordu.


--- Daha fazla okuma ---

System.Net.Mail.MailAddress belgeleri

Geçerli bir e-posta adresini oluşturan öğelerin açıklaması


23
Aslında bu yanlış değil. a @ a geçerli bir e-posta adresidir. Bkz. Haacked.com/archive/2007/08/21/… Aslında, tırnak içinde bir adres kullanırsanız bu yöntem yanlış sonuçlar döndürür.
Karikatür

53
+1: System.Net.MailPosta göndermek için sınıfları kullanıyorsanız, muhtemelen .NET kullanıyorsanız en iyi yanıt budur . Bu tür bir doğrulama kullanmaya karar verdik çünkü posta gönderemediğimiz e-posta adreslerini - geçerli adresleri bile - kabul etmemizin bir anlamı yok.
Greg Beech

24
Ben tavsiye etmiyorum. Doğru döner:IsValidEmail("this is not valid@email$com");
Kakashi

15
Sorunların çoğu MailAddress'in DisplayName'i de ayrıştırmaya çalıştığı için görünüyor, bu nedenle "single space@domain.com" DisplayName "single" ve Address "space@domain.com" adreslerine ayrılıyor. Bunun için bir düzeltme: return (addr.Address == email);
Stuart

18
Bunu severim; Zorlamanın gerçek teknik özelliklerden daha kısıtlayıcı olmasını sağlayamıyorum. Yanlış negatifler yanlış pozitiflerden çok daha kötüdür ("e-
Casey

242

Bu eski bir sorudur, ancak daha yeni olanlar da dahil olmak üzere SO'da bulduğum tüm cevaplar buna benzer şekilde cevaplanmaktadır. Ancak, .Net 4.5 / MVC 4'te System.ComponentModel.DataAnnotations'dan [EmailAddress] ek açıklamasını ekleyerek bir forma e-posta adresi doğrulaması ekleyebilirsiniz, bu yüzden neden yalnızca yerleşik işlevselliği kullanamadığımı merak ediyordum. Genel olarak net.

Bu işe yarıyor gibi görünüyor ve bana oldukça zarif geliyor:

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
Harika, ancak MS'in bunu kendi dokümanları ile kabul edememesi hayal kırıklığı yaratıyor . Bu js@proseware.com9'u reddediyor
Casey

13
Örneğin - TLD için bir adres kabul ettiğinden EmailAddressAttributedaha az izin verildiğini unutmayın . Mümkün olduğunca müsamahakar olmanız gerekiyorsa akılda tutulması gereken bir şey. System.Net.Mail.MailAddressMailAddress
Aaroninus

5
@Cogwheel: Cevap yorumların herhangi bir yerinde bulunuyorsa, muhtemelen cevabın ana gövdesine eklenmelidir.
hofnarwillie

6
@hofnarwillie: ana gövdede, ancak yorumlar ayrıntılı. Amacınız kullanıcılarınızı kızdırmamaksa, doğrulamanız spesifikasyondan daha kısıtlayıcı olmamalıdır. Bir e-postanın geçerli olup olmadığını gerçekten doğrulamanın tek yolu test mesajı göndermektir.
Karikatür

4
Lütfen foo.IsValid(null);geri döndüğünü unutmayın true.
urig

62

İşi benim için yapan bu tek astar yöntemini kullanıyorum-

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

Yorumlara göre, source(e-posta adresi) boşsa bu "başarısız" olacaktır .

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

1
Bu benim için işe yaramıyor; "Veri Ek Açıklamaları" mevcut değil ... bir montaj başvurusu eksik mi? " Hangi referansı eklemem gerekiyor?
Shannon

Kaynak null olduğunda bu true değerini döndürür. Bkz. Msdn.microsoft.com/en-us/library/hh192424 "Belirtilen değer geçerliyse veya null ise true; aksi takdirde false".
jao

2
Daha iyi bir versiyon:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
Sebastian Hofmann

7
Ya da daha iyisi:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander

1
Bu uzatma yönteminin sessizce falseboş dizeler için dönmesi gerektiğini düşünmüyorum . En neden (daha iyi daha iyi) ++ sürümünü önermek O: public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());. Şimdi gidip Daha İyi Daha İyi Versiyonistler Reform Kilisesi'ni bulacağım.
Marc.2377

41

.net 4.5 System.ComponentModel.DataAnnotations.EmailAddressAttribute ekledi

Şuraya göz atabilirsiniz: EmailAddressAttribute kaynağına , bu dahili olarak kullandığı Regex'tir:

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
Ne yazık ki EmaillAddressAttribute, e-posta için geçerli bir karakter olmayan Ñ'ye izin veriyor
BZ

16
@BZ Evet, öyle. Neden olmadığını düşünüyorsun?
Casey

@Chad Grant: Bu bir C # sürümüdür. Lütfen bir VB.Net sağlayabilir misiniz? Çünkü bu \\ to \ gibi karakterlerden kaçacak veya bir dize kelimesi kelimesine sağlayabilirsiniz.
Nikhil Agrawal

3
Bu işe yarıyor ama unutma RegexOptions.IgnoreCaseçünkü bu kalıp büyük harflere açıkça izin vermiyor!
Chris

1
Regex'in çok kasıtlı olduğunu unutmayın: "Bu özellik, jquery doğrulamasına eşdeğer sunucu tarafı e-posta doğrulaması sağlar ve bu nedenle aynı normal ifadeyi paylaşır".
Ohad Schneider

38

Phil'in cevabını # 1'den aldım ve bu sınıfı yarattım. Buna şöyle deyin:bool isValid = Validator.EmailIsValid(emailString);

İşte sınıf:

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
Sadece küçük bir tane, ama ben kullanacağım: return (! String.IsNullOrEmpty (emailAddress)) && ValidEmailRegex.IsMatch (emailAddress);
Marc

Bu sadece korku :)
Alexandru Dicu

31

Şahsen, içinde bir @ sembolü olduğundan emin olmanız gerektiğini söyleyebilirim, muhtemelen bir. karakter. Değişken doğrulukta kullanabileceğiniz birçok regexes var, ancak bunların çoğunun geçerli e-posta adreslerini bıraktığını veya geçersiz adreslerin geçmesine izin verdiğini düşünüyorum. İnsanlar sahte bir e-posta adresi koymak isterse, sahte bir e-posta adresi koyacaktır. E-posta adresinin yasal olduğunu ve kişinin bu e-posta adresini kontrol ettiğini doğrulamanız gerekiyorsa, onlara gerçek bir adres olduğunu doğrulayabilmeleri için onlara özel kodlanmış bir bağlantı içeren bir e-posta göndermeniz gerekir.


6
Şahsen bundan biraz daha doğrulama yapman gerektiğini düşünüyorum. Birisi Bobby Table'ın e-posta adresini veya daha kötüsünü denemek zorunda.
Luke Quinane

31
Hazırlanan ifadeler kullanıyorsanız, bobby table'ın e-posta adresindeki sorun nedir? Geçerli e-posta adreslerinden bahsediyoruz, geçerli bir e-posta adresi oluşturan şeyle ilgisi olmayan başka şeylerden değil, SQL sorgulama sorunlarını almamanız için SQL sorgularının nasıl düzgün bir şekilde yapılacağı gibi.
Kibbee

Sanırım birisinin oraya ne koyacağını bilmiyorsunuz, ancak kötü niyetli bir kişi değerin sonunda posta sisteminize beslenebileceğini biliyor. Sadece derinlemesine savunmayı ve biraz daha katı olmayı tercih ederim.
Luke Quinane

10
Bu endişe edilecek posta sistemi için. Sadece başka bir sistemle ilgili bir güvenlik sorunu olabileceği için mükemmel geçerli e-posta adreslerini reddetmek istemem. Güvenlik sorunlarına neden olması için tüm e-posta sunucunuzun ihtiyacı olan hatalı biçimlendirilmiş bir e-posta adresiyse, muhtemelen başka bir sunucuya geçmelisiniz.
Kibbee

4
Derinlemesine savunma, yalnızca güvenlik soğanınızın her seviyesi çürümüş değilse çalışır. Bir çürük katman, tüm soğanı bozduğunuz anlamına gelir. Sun'ın µ-law kodlamasındaki güvenlik açıklarına karşı savunmak istediğiniz için "foo@example.com.au" yu reddetmek mantıklı değil mi? Gülme, başıma geldi. Burada yorum yapmamın nedeni Medicare Australia'nın ".au" adreslerine, sadece ".com" a izin vermemesidir. Ayrıca Mark Swanson, "E-posta nasıl doğrulanmaz", mdswanson.com/blog/2013/10/14/…
ManicDee

17

Bence en iyi yol aşağıdaki gibidir:

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

Bu statik işleve genel bir sınıfta sahip olabilirsiniz.


Bu yanıt, alan adı bölümünde TLD olan bir adresi kabul etmiyor.
Simone

15

Kısa ve doğru kod

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
Çözüm için teşekkürler
Jack Gajanan

Bunu önlemek için genel statik bool IsValidEmail (bu dize e-postası) genel statik bool IsValidEmail (dize e-posta) değiştirmek zorunda kaldım: stackoverflow.com/questions/10412233/…
Goner Doug

@Goner Doug, bu işlev böyle çalışacaktır. (Bool flag = EmailAddress.IsValidEmail ())
Naveen

2
formuma eklendiğinde derleyici sorunlarına yol açmamak için "BU" nun kaldırılması gerekiyordu.
Geyik Doug

@Goner Doug, İşlevi böyle çalışacak. string email = "abc@xyz.com"; if (email.IsValidEmail ()) {dönüş yanlış; } else {return true;}
Naveen

14

En zarif yol .Net'in yerleşik yöntemlerini kullanmaktır.

Bu yöntemler:

  • Denenir ve test edilir. Bu yöntemler kendi profesyonel projelerimde kullanılıyor.

  • Dahili olarak güvenilir ve hızlı düzenli ifadeler kullanın.

  • C # için Microsoft tarafından yapılmıştır. Tekerleği yeniden icat etmeye gerek yok.

  • Bir bool sonucu döndür. Doğru, e-postanın geçerli olduğu anlamına gelir.

Net 4.5 ve üstü kullanıcılar için

Bu Referansı projenize ekleyin:

System.ComponentModel.DataAnnotations

Şimdi aşağıdaki kodu kullanabilirsiniz:

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

Kullanım örneği

İşte beyan etmek için bazı yöntemler:

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;

}

... ve bunları eylem halinde gösteren kod:

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

}

Ayrıca, bu örnek:

  • Tek bir dize, noktalı virgül tarafından dağıtılan 0, bir veya daha fazla e-posta adresi içermek için kullanıldığından, spesifikasyonun ötesine uzanır ;.
  • EmailAddressAttribute nesnesinin IsValid yönteminin nasıl kullanılacağını açıkça gösterir.

Alternatif, .Net sürümü 4.5'ten az olan kullanıcılar için

Net 4.5'in kullanılamadığı durumlarda, aşağıdaki çözümü kullanıyorum:

Özellikle, ben kullanın:

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 Bir EmailAddressAttribute yanıtı görmedim ve input == .Address üzerinde bir kontrol ile yeni MailAddress () kullanan bir cevap görmedim, bu yüzden oldukça yararlı olduğunu düşünüyorum. Yorumları okumadan kabul edilen cevap oldukça yanlıştır. yeni MailAddress ("Foobar Some@thing.com") bunu kanıtlıyor.
Ocak

@Jan fwiw, Manik Knickerless'ı EmailAddressAttributedört aydan kısa bir sürede yendi , ancak bu nullsorunu yakaladı .
Ruffin

7

Dürüst olmak gerekirse, üretim kodunda yaptığım en iyi şey bir @sembolü kontrol etmektir .

Asla e-postaları tam olarak doğrulayacak bir yerim yok. Gerçekten geçerli olup olmadığını nasıl gördüğümü biliyor musun? Gönderildiyse. Olmasaydı, kötü, eğer yaptıysa, hayat iyidir. Tüm bilmem gereken bu.


6

Bu normal ifadenin, @ işaretinden başka bir şey olup olmadığını kontrol etmekle garip uç durumları kabul etmek arasında iyi bir takas olduğunu düşünüyorum:

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

En azından @ işaretinin etrafına bir şey koymanızı ve en azından normal görünen bir alan koymanızı sağlar.


Ben aynı regex ile geldi;) Gerçi geçersiz karakterlere izin veriyor
Stefan

Bu yanıt, alan adı bölümünde TLD kabul etmiyor.
Simone

@Simone muhtemelen hiç kimsenin alan adında TLD ile e-posta adresleri pratikte olmasa da: yorumlarda serverfault.com/a/721929/167961 notu bu günlerde yasaklanmış olabilir
Matthew Lock

@MatthewLock Bir intranet adresi olabilir mi? Gibi bob@companyinternalmi?
Simone

@Simone gerçek hayatta herkes bu düzeni kullanıyor mu?
Matthew Lock

4

E-posta adresi doğrulaması göründüğü kadar kolay değildir. Sadece normal bir ifade kullanarak bir e-posta adresini tam olarak doğrulamak teorik olarak imkansızdır.

Benim göz atın blog yazısı konu ve FParsec kullanarak bir F # uygulanmasına ilişkin bir tartışma için bu konuda. [/ shameless_plug]


1
Alternatif yaklaşımların listesini beğendim; çok ilginç.
Luke Quinane

1
Ilginç yazı. Ama ciddiye e-posta adreslerine kimler yorum yapıyor ve bunları iç içe koyuyor?
Matthew Lock

3
@matthew IETF'in buna neden izin verdiğini bilmiyorum, ancak bu mümkün , bu yüzden kapsamlı bir doğrulama bunu hesaba katmalı .
Mauricio Scheffer

4

İşte cevabım - Phil'in çözümü "someone@q.com" gibi tek harfli alanlar için başarısız oluyor. İster inanın ister inanmayın, bu kullanılır =) (örneğin centurylink'e gider).

Phil'in yanıtı da sadece PCRE standardıyla çalışacak ... bu yüzden C # alacak, ancak javascript bombalayacak. Javascript için çok karmaşık. Yani Phil'in çözümünü mvc doğrulama özellikleri için kullanamazsınız.

İşte benim normal ifadem. MVC doğrulama özellikleriyle iyi çalışır.
- @ öncesi her şey basitleştirildi, böylece en azından javascript çalışacak. Değişim sunucusu bana bir 5.1.3 vermediği sürece burada rahatlatıcı doğrulama tamam. @ @ 'Den sonraki her şey Phil'in tek harfli alanlar için değiştirilmiş çözümüdür.

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]$";

System.net.mail MailMessage () kullanmanızı öneren kişiler için, bu esnek bir yol. Elbette, C # e-postayı kabul edecek, ancak daha sonra e-posta göndermeye çalıştığınızda exchange sunucusu 5.1.3 çalışma zamanı hatasıyla bombalayacak.


en iyi düşünceli / makul / gerçek dünya cevabı gibi görünüyor, teşekkürler Ralph!
Mart'ta Fattie

bu şimdiye kadarki en iyi cevap! basket@ballGeçerli bir e-posta adresi olarak kabul edilen kötü bir çözümün, tüm bu oyların yanı sıra doğru cevabı kazandığına inanamıyorum. Yine de teşekkürler!
disasterkid

Teşekkürler bu en iyi çözümdür ve cevap kabul edilmelidir.
Bat_Programmer

3

Gerçekten ve ben gerçekten bir e-posta adresinin geçerli olup olmadığını bilmek istiyorsanız ... posta değiştiriciden bunu kanıtlamasını isteyin, normal ifadeye gerek yoktur. İstenirse kod sağlayabilirim.

Genel adımlar aşağıdaki gibidir: 1. E-posta adresinin bir etki alanı adı bölümü var mı? (@> 0 dizini) 2. bir DNS sorgusu kullanarak etki alanında bir posta değiştirici olup olmadığını sorun 3. posta değiştiriciye tcp bağlantısını açın 4. smtp protokolünü kullanarak, alıcıya e-posta adresini kullanarak sunucuya bir ileti açın 5. sunucunun yanıtını ayrıştırın. 6. bugüne kadar yaptıysanız mesajdan çıkın, her şey iyidir.

Tahmin edebileceğiniz gibi, çok pahalı zaman akıllıca ve smtp'ye dayanıyor, ama işe yarıyor.


Bu arayüzler için sahte, taslak ve / veya alay oluşturdunuz mu?
Mark A

1
Bu işe yaramaz. Bir e-posta adresinin UZUN kullanımdan kaldırıldığını / kullanılmadığını doğrulamak için smtp protokolü. Spam gönderenler bu işlevi kullandığından posta sunucularında etkinleştirmek kötü bir uygulama olarak kabul edilir.
Chad Grant

Önerinizi 2'ye kadar tutacağım. Bilinen bir alan adı modelini kontrol etmekten çok daha fazla geleceğe dönük.
Simone

Nitpicking, ancak "bir posta değiştirici var" tanımlamak ? MX kaydı yoksa, SMTP, RFC2821 / 5321 uyarınca A / AAAA kaydına geri dönmelidir. Bir MX kaydı varsa, yine de bir posta değiştiricisinin bulunduğunu göstermeyebilir (RFC7505). Gerçekten, tek yol onlara bir harekete geçirici mesaj bağlantısı olan bir posta göndermek ve cevap
vermelerini

2

Genel olarak konuşursak, e-posta adreslerini doğrulamak için düzenli bir ifade bulmak kolay bir şey değildir; bu yazının yazıldığı sırada, bir e-posta adresinin sözdizimi nispeten yüksek sayıda standardı izlemelidir ve bunların tümünü düzenli bir ifade içinde uygulamak pratik olarak mümkün değildir!

Hepsini takiben e-posta adreslerini doğrulayabilen olgun bir .NET kütüphanesi EmailVerify.NET'imizi denemenizi önemle tavsiye ederim. güncel IETF standartları (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 ve 5322 RFC) , ilgili DNS kayıtlarını test eder, hedef posta kutularının mesajları kabul edip edemeyeceğini kontrol eder ve hatta belirli bir adresin tek kullanımlık olup olmadığını söyleyebilir.

Feragatname: Bu bileşenin baş geliştiricisiyim.


Etkileyici! "Ardından, belirtilen e-posta adresinden sorumlu posta değiştiriciyle iletişim kurmaya çalışır ve gerçek bir posta sunucusunu taklit ederek bu sunucu ile sahte bir SMTP iletişim kutusu başlatır. Bu şekilde, sunucunun adres için e-postaları işleyebilmesini sağlar. Birçok SMTP sunucusu aslında spam göndericilere karşı koruma olarak yanlış olumlu yanıtlar verin: Bu sorunun üstesinden gelmek için, EmailVerify for .NET, hedef posta değiştiriciyi farklı fabrikasyon adreslerle birden çok kez sorgulamaya çalışır. "
Matthew Lock

Teşekkürler, @MatthewLock;)
Efran Cobisi

Güzel, ama sadece ücretli sürümleri görüyorum. Topluluk / OpenSource sürümü için herhangi bir planınız var mı?
Ohad Schneider

1
@OhadSchneider Evet: SaaS e-posta doğrulama hizmetimiz Verifalia aracılığıyla e-posta doğrulama teknolojimizin ücretsiz bir sürümünü sunuyoruz . Verifalia, .NET dahil önemli yazılım geliştirme platformları için ücretsiz ve açık kaynaklı SDK'larla birlikte gelir .
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;
        }

A@b.info dosyasını geçerli bir e-posta adresi olarak doğrulayamaz.
Ray Cheng

2

FluentValidation kullanıyorsanız şu kadar basit bir şey yazabilirsiniz:

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

@Cogwheel cevabında küçük bir değişiklik

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

Bu yardımcı olmaz ... geçerli olmayan Console.WriteLine(MailAddress("asdf@asdf.").Address);"asdf @ asdf." Çıktıları.
Langdon

.net kendi geçerlilik tanımına sahip gibi görünüyor. ilgili tartışma
waitforit

2

Burada çok güçlü cevaplar var. Ancak, geri adım atmamızı tavsiye ederim. @Cogwheel, https://stackoverflow.com/a/1374644/388267 sorusuna cevap veriyor . Bununla birlikte, doğrulanan e-posta adreslerinin çoğu geçersizse, toplu doğrulama senaryosunda maliyetli olabilir. Try-catch bloğuna girmeden önce biraz mantık kullanmanızı öneriyorum. Aşağıdaki kod RegEx kullanılarak yazılmış olabilir ama yeni geliştiriciler anlamak için pahalı olabilir biliyorum. Bu benim twopence değer:

    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

@Cogwheel en çok oy alan cevap en iyi cevap ancak ben trim()dize yöntemi uygulamak için denedim böylece dize başından sonuna kadar tüm kullanıcı beyaz boşluk kırpacaktır . Tam örnek için aşağıdaki kodu kontrol edin.

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

Bunun riski, kaynaktan farklı bir e-posta adresini doğrulamanızdır ve belirtilen e-posta adresinin (bu durumda) zararsız sürümüne posta gönderebileceğinizi düşünmenizi sağlar. Daha iyi bir yaklaşım SanitizeEmail(string email), e-postayı doğrulamak ve göndermek için bu yöntemin sonucunu kullanarak ayrı bir yöntem yapmak olacaktır .
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

E-posta dizesinin doğru biçim mi, yoksa yanlış biçim mi olduğunu kontrol edin 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

/ "New EmailAddressAttribute ();" oluştururken kullanılan Dahili Regex'i kullanma .Net4.5 >>> 'de System.ComponentModel.DataAnnotations kullanarak bileşen; // Bir E-posta Adresini Doğrulamak İçin ...... Test Edildi ve Çalışıyor.

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

Ayrıca, bunu kullanabilirsiniz:

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


bu e-posta için doğru diyor: "fulya_42_@hotmail.coö" ve mandrill api'de hata veriyor
MonsterMMORPG

1
İlk olarak, e-posta geçerli wrt example@example.co veya example@example.com .... E-posta son "ö" karakteri dışında geçerli tüm dize ve ölçütlere sahiptir ve bu karakteri doğrulamak için kolayca basit bir koşul ekleyebilirsiniz . İkincisi, bu mandrill api hatası hakkında emin değilim, bu başka bir ortamda / api'de kullandığım kullanım yönteminizi doğrulamak isteyebilirsiniz ve benim için iyi oldu.
Aina Ademola C

1

Ben Poyson 1'in cevabını şöyle özledim:

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

E-posta kimliğini tanımlamanın basit yolu geçerlidir veya yoktur.

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

Normalde js yerine C # regex kültür sorunu var. Bu nedenle e-posta kontrolü için ABD modunda normal ifadeyi kullanmamız gerekiyor. ECMAScript modunu kullanmazsanız, dil özel karakterleriniz AZ'de normal ifade ile ifade edilir.

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

Virgülleri, yorumları, Unicode karakterlerini ve IP (v4) etki alanı adreslerini başarıyla doğruladığı için bu regex'i kullandım.

Geçerli adresler:

"" @ example.org

(comment)test@example.org

тест@example.org

ტესტი @ example.org

Test @ [192.168.1.1'dir]

 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

Regex (zayıf okunabilirliği için sevmiyorum) kullanmadan basit bir tane:

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

Örnekler:

  • 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

Basit olması amaçlanmıştır ve bu nedenle boşluk içeren (genellikle izin verilen) parantezli alan e-postaları, IPv6 adresleri olan e-postalar vb. Gibi nadir durumlarla ilgilenmez.


1

İşte kontrol etmeniz gereken soruya bir cevap.

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

@Cogwheel cevabına dayanarak SSIS ve "Script Bileşeni" için çalışan değiştirilmiş bir çözümü paylaşmak istiyorum:

  1. "Komut Dosyası Bileşeni" ni Veri Akışı bağlantınıza yerleştirin ve açın.
  2. "Giriş Sütunları" bölümünde, E-Posta Adreslerini içeren alanı "ReadWrite" olarak ayarlayın ('fieldName' örneğinde).
  3. "Komut Dosyası" bölümüne geri dönün ve "Komut Dosyasını Düzenle" yi tıklayın. Kod açıldıktan sonra beklemeniz gerekir.
  4. Bu kodu doğru yönteme yerleştirin:

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

Ardından, tüm geçersiz kayıtları veya yapmak istediklerinizi filtrelemek için Koşullu Bölme kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.