【问题标题】:C# code to validate email address验证电子邮件地址的 C# 代码
【发布时间】:2010-11-24 19:46:24
【问题描述】:

验证字符串是否为有效电子邮件地址的最优雅的代码是什么?

【问题讨论】:

标签: c# email email-validation


【解决方案1】:

这个怎么样?

bool IsValidEmail(string email)
{
    var trimmedEmail = email.Trim();

    if (trimmedEmail.EndsWith(".")) {
        return false; // suggested by @TK-421
    }
    try {
        var addr = new System.Net.Mail.MailAddress(email);
        return addr.Address == trimmedEmail;
    }
    catch {
        return false;
    }
}

根据 Stuart 的评论,这会将最终地址与原始字符串进行比较,而不是始终返回 true。 MailAddress 尝试将带有空格的字符串解析为“显示名称”和“地址”部分,因此原始版本返回误报。


为了澄清,问题是询问特定字符串是否是电子邮件地址的有效表示,而不是电子邮件地址是否是发送消息的有效目的地。为此,唯一真正的方法是发送消息确认。

请注意,电子邮件地址比您最初想象的要宽容。这些都是完全有效的形式:

  • cog@wheel
  • “橘子齿轮”@example.com
  • 123@$.xyz

对于大多数用例,虚假的“无效”比虚假的“有效”对您的用户和未来的验证更糟糕。这是此问题的article that used to be the accepted answer(该答案已被删除)。它有更多的细节和一些关于如何解决问题的其他想法。

提供健全性检查对于用户体验来说仍然是一个好主意。假设电子邮件地址有效,您可以查找已知的顶级域,检查域中的 MX 记录,检查常见域名 (gmail.cmo) 中的拼写错误等。然后向用户发出警告有机会说“是的,我的邮件服务器确实允许 ??? 作为电子邮件地址。”


至于对业务逻辑使用异常处理,我同意这是应该避免的。但这是方便和清晰可能胜过教条的情况之一。

此外,如果您对电子邮件地址进行任何其他操作,则可能需要将其转换为 MailAddress。即使您不使用这个确切的功能,您也可能希望使用相同的模式。您还可以通过捕获different exceptions 来检查特定类型的故障:null、empty 或 invalid format。


--- 进一步阅读---

Documentation for System.Net.Mail.MailAddress

Explanation of what makes up a valid email address

【讨论】:

  • 其实这并没有错。 a@a 是一个有效的电子邮件地址。见haacked.com/archive/2007/08/21/…事实上,如果你使用带引号的地址,这个方法确实会返回不正确的结果。
  • +1:如果您使用System.Net.Mail 类发送邮件,这是最好的答案,如果您使用.NET,您可能就是这样。我们之所以决定使用这种类型的验证,仅仅是因为我们接受电子邮件地址(即使是有效地址)毫无意义,因为我们无法向其发送邮件。
  • 我不推荐。它返回真:IsValidEmail("this is not valid@email$com");
  • 很多问题似乎是因为 MailAddress 也试图解析 DisplayName,所以“single space@domain.com”解析为 DisplayName“single”和地址“space@domain.com” .对此的解决方法是:return (addr.Address == email);
  • 我喜欢这个;我没有强迫比实际规范更严格。误报比误报更糟糕(“你的意思是我的电子邮件无效吗?”)
【解决方案2】:

这是一个老问题,但我在 SO 上找到的所有答案,包括最近的答案,都与这个答案类似。但是,在 .Net 4.5 / MVC 4 中,您可以通过从 System.ComponentModel.DataAnnotations 添加 [EmailAddress] 注释来向表单添加电子邮件地址验证,所以我想知道为什么我不能只使用来自 .网络一般。

这似乎可行,而且在我看来相当优雅:

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

【讨论】:

  • 很酷,虽然令人失望的是 MS 无法让这与 their own documentation 一致。这拒绝 js@proseware.com9
  • 请注意,EmailAddressAttributeSystem.Net.Mail.MailAddress 更宽松 - 例如,MailAddress 接受 TLD 的地址。如果您需要尽可能宽容,请记住一些事情。
  • @Cogwheel:如果答案位于 cmets 中的某个位置,则可能应该将其添加到答案的主体中。
  • @hofnarwillie:它在主体中,但 cmets 详细说明。如果您的目标是不激怒您的用户,那么您的验证不应该比规范更具限制性。真正验证电子邮件是否有效的唯一方法是发送测试消息。
  • 请注意foo.IsValid(null); 返回true
【解决方案3】:

我使用这种为我工作的单班轮方法-

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

根据 cmets,如果 source(电子邮件地址)为空,这将“失败”。

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

【讨论】:

  • 这对我不起作用;我得到,“'数据注释'不存在......你是否缺少程序集参考?”我需要添加哪个参考?
  • 如果 source 为空,这将返回 true。见msdn.microsoft.com/en-us/library/hh192424“如果指定的值有效或为null,则为true;否则为false。”
  • 更好的版本:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
  • 或者更好:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
  • 我认为这个扩展方法不应该为空字符串静默返回false。这就是为什么我提出(更好更好)++ 版本:public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());。我现在要去寻找更好更好的版本主义者的归正教会。
【解决方案4】:

.net 4.5 添加了System.ComponentModel.DataAnnotations.EmailAddressAttribute

您可以浏览EmailAddressAttribute's source,这是它内部使用的正则表达式:

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])))\.?$";

【讨论】:

  • 不幸的是,EmaillAddressAttribute 允许 Ñ 这不是电子邮件的有效字符
  • @BZ 是的。为什么你认为不是?
  • @Chad Grant:这是一个 C# 版本。你能提供一个VB.Net吗?因为这会将 \\ 到 \ 之类的字符转义,或者您可以逐字提供字符串。
  • 这可行,但不要忘记RegexOptions.IgnoreCase,因为这种模式不允许明确允许大写字母!
  • 请注意,Regex 是经过深思熟虑的:“此属性提供与 jquery validate 等效的服务器端电子邮件验证,因此共享相同的正则表达式”。
【解决方案5】:

我从 #1 中获取了 Phil 的答案并创建了这个课程。 像这样称呼它:bool isValid = Validator.EmailIsValid(emailString);

这是课程:

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

【讨论】:

  • 只是一个小的,但我会使用:return (!string.IsNullOrEmpty(emailAddress)) && ValidEmailRegex.IsMatch(emailAddress);
  • 这只是恐怖:)
  • 这不会验证具有 1 个字符域的电子邮件。即:bla@a.com
  • @Владимiръ 你运行代码了吗?上次有人说它不起作用时,我启动了一个编码环境,它确实正确验证了。我已经有大约 8 年没有使用 C#了,我真的很好奇你是否知道它不起作用,或者你是否正在阅读代码并说它不起作用。
【解决方案6】:

就个人而言,我会说你应该确保那里有一个 @ 符号,可能还有一个 .特点。您可以使用许多正则表达式来获得不同的正确性,但我认为其中大多数都会遗漏有效的电子邮件地址,或者让无效的电子邮件地址通过。如果人们想输入一个假的电子邮件地址,他们就会输入一个假的。如果您需要验证电子邮件地址是否合法,并且该人控制该电子邮件地址,那么您需要向他们发送带有特殊编码链接的电子邮件,以便他们验证它确实是一个真实地址。

【讨论】:

  • 我个人认为你应该做更多的验证。肯定有人会尝试使用 Bobby Table 的电子邮件地址或更糟。
  • 如果您使用准备好的语句,bobby table 的电子邮件地址有什么问题。我们谈论的是有效的电子邮件地址,而不是与有效电子邮件地址无关的其他事情,例如如何正确执行 SQL 查询,以免遇到 SQL 注入问题。
  • 我猜你不知道有人会在里面放什么,但恶意的人知道这个值最终可能会输入你的邮件系统。我只是更喜欢深入防守并更严格一些。
  • 这是邮件系统要操心的。我不会仅仅因为它可能是其他系统的安全问题而拒绝完全有效的电子邮件地址。如果您的电子邮件服务器只需要一个格式错误的电子邮件地址来导致安全问题,那么您可能应该切换到另一台服务器。
  • 深度防御只有在你的安全洋葱的每一层都没有腐烂的情况下才有效。一层腐烂意味着你破坏了整个洋葱。拒绝“foo@example.com.au”,因为您想防御 Sun 的 µ-law 编码中的漏洞是没有意义的,不是吗?别笑,这件事发生在我身上。我在这里评论的原因是澳大利亚联邦医疗保险不允许“.au”地址,只有“.com”。另请阅读 Mark Swanson,“如何不验证电子邮件”,mdswanson.com/blog/2013/10/14/…
【解决方案7】:

简短而准确的代码

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

【讨论】:

  • 我不得不将 public static bool IsValidEmail(this string email) 更改为 public static bool IsValidEmail(string email) 以避免这个:stackoverflow.com/questions/10412233/…
  • @Goner Doug,这个功能会像这样工作。(bool flag = EmailAddress.IsValidEmail())
  • 需要删除“THIS”以避免在添加到我的表单时导致编译器问题。
  • @Goner Doug,它的功能将像这样工作。字符串电子邮件=“abc@xyz.com”; if (email.IsValidEmail()){ return false; }else { 返回真;}
【解决方案8】:

我认为最好的方法如下:

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

你可以在一个通用类中拥有这个静态函数。

【讨论】:

  • 此答案不接受域部分中带有 TLD 的地址。
【解决方案9】:

最优雅的方式是使用 .Net 的内置方法。

这些方法:

  • 经过试验和测试。这些方法在我自己的专业项目中使用。

  • 在内部使用正则表达式,可靠且快速。

  • 由 Microsoft 为 C# 制造。无需重新发明轮子。

  • 返回布尔结果。 True 表示电子邮件有效。

适用于 .Net 4.5 及更高版本的用户

将此引用添加到您的项目中:

System.ComponentModel.DataAnnotations

现在您可以使用以下代码:

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

使用示例

这里有一些声明方法:

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;

}

...以及演示它们的代码:

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

}

另外,这个例子:

  • 超出规范,因为单个字符串用于包含 0 个、一个或多个由分号 ; 分隔的电子邮件地址。
  • 清楚地演示了如何使用 EmailAddressAttribute 对象的 IsValid 方法。

替代方案,适用于 .Net 版本低于 4.5 的用户

对于.Net 4.5 不可用的情况,我使用以下解决方案:

具体来说,我使用:

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;

}

【讨论】:

  • @ThomasAyoub 我还没有看到 EmailAddressAttribute 答案,也没有使用 new MailAddress() 检查输入 == .Address 的答案,所以我认为它非常有用。如果不阅读 cmets,则接受的答案是非常错误的。 new MailAddress("Foobar Some@thing.com") 证明了这一点。
  • @Jan fwiw, Manik 在不到四个月的时间内击败了 Knickerless 到 EmailAddressAttribute,尽管这个确实抓住了 null 的问题。
【解决方案10】:

我发现这个正则表达式在检查不仅仅是@标记和接受奇怪的边缘情况之间是一个很好的权衡:

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

它至少会让你在@标记周围加上一些东西,并且至少放置一个看起来正常的域。

【讨论】:

  • 我想出了相同的正则表达式;)它确实允许无效字符
  • 此答案不接受域部分中的 TLD。
  • @Simone 可能没有人在域部分拥有带有 TLD 的电子邮件地址,但实际上:serverfault.com/a/721929/167961 在 cmets 中注意这些天可能被禁止
  • @MatthewLock 会不会是内网地址?喜欢bob@companyinternal
  • @Simone 现实生活中真的有人使用这个方案吗?
【解决方案11】:

说实话,在生产代码中,我所做的最好的事情就是检查 @ 符号。

我永远无法完全验证电子邮件。你知道我怎么看它是否真的有效吗?如果寄过去了。如果没有,那就糟糕了,如果有,生活就是美好的。这就是我需要知道的全部内容。

【讨论】:

    【解决方案12】:

    电子邮件地址验证并不像看起来那么容易。实际上,仅使用正则表达式完全验证电子邮件地址在理论上是不可能的。

    查看我的blog post,了解有关该主题的讨论以及使用 FParsec 的 F# 实现。 [/shameless_plug]

    【讨论】:

    • 我喜欢你的替代方法列表;非常有趣。
    • 有趣的文章。但说真的,谁在电子邮件地址中放置了 cmets 和嵌套的 cmets?
    • @matthew 我不知道为什么 IETF 甚至允许这样做,但这是可能的,因此必须考虑到彻底的验证。
    【解决方案13】:

    我只想指出,最近在 .NET 文档中添加了有关电子邮件验证的内容,也使用了正则表达式操作。 可以在此处找到对其实施的详尽解释。

    https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format

    为方便起见,以下是他们的测试结果列表:

    //       Valid: david.jones@proseware.com
    //       Valid: d.j@server1.proseware.com
    //       Valid: jones@ms1.proseware.com
    //       Invalid: j.@server1.proseware.com
    //       Valid: j@proseware.com9
    //       Valid: js#internal@proseware.com
    //       Valid: j_9@[129.126.118.1]
    //       Invalid: j..s@proseware.com
    //       Invalid: js*@proseware.com
    //       Invalid: js@proseware..com
    //       Valid: js@proseware.com9
    //       Valid: j.s@server1.proseware.com
    //       Valid: "j\"s\""@proseware.com
    //       Valid: js@contoso.中国
    

    【讨论】:

      【解决方案14】:

      这是我的答案——对于像“someone@q.com”这样的单字母域,Phil 的解决方案失败了。信不信由你,这是用过的 =)(例如,去世纪链接)。

      Phil 的回答也只适用于 PCRE 标准......所以 C# 会接受它,但 javascript 会爆炸。对于javascript来说太复杂了。所以你不能使用 Phil 的解决方案进行 mvc 验证属性。

      这是我的正则表达式。它可以很好地与 MVC 验证属性一起使用。
      - @ 之前的所有内容都被简化了,因此至少 javascript 可以工作。只要交换服务器没有给我 5.1.3,我就可以在这里放松验证。 - @ 之后的所有内容都是 Phil 针对单字母域修改的解决方案。

      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() 的人来说,这很灵活。当然,C# 会接受电子邮件,但是一旦您尝试发送电子邮件,Exchange 服务器就会出现 5.1.3 运行时错误。

      【讨论】:

      • 这似乎是最好的最周到/合理/现实世界的答案,谢谢拉尔夫!
      • 这是迄今为止最好的答案!我无法相信接受basket@ball 作为有效电子邮件地址的错误解决方案已获得正确答案以及所有这些赞成票。还是谢谢!
      • 谢谢,这是最好的解决方案,应该被接受。
      【解决方案15】:

      如果您真的和我的意思是真的想知道电子​​邮件地址是否有效...请邮件交换器证明这一点,不需要正则表达式。如果需要,我可以提供代码。

      一般步骤如下: 1.电子邮件地址有域名部分吗? (@ > 0 的索引) 2.使用DNS查询询问域是否有邮件交换器 3.打开tcp连接到邮件交换器 4. 使用smtp协议,以邮件地址为接收者打开一条消息到服务器 5.解析服务器的响应。 6. 到此为止就退出消息,一切都很好。

      这正如你所想的那样,在时间上非常昂贵并且依赖于 smtp,但它确实有效。

      【讨论】:

      • 您是否为这些接口创建了假冒、存根和/或模拟?
      • 那行不通。验证电子邮件地址的 smtp 协议已长期被弃用/未使用。在邮件服务器上启用它被认为是不好的做法,因为垃圾邮件发送者使用该功能。
      • 我会将您的建议保留到第 2 点。比检查已知域名模式更具前瞻性。
      • 吹毛求疵,但定义“有一个邮件交换器”?如果不存在 MX 记录,则 SMTP 应根据 RFC2821/5321 回退到 A/AAAA 记录。如果确实存在 MX 记录,它仍然可能不指示存在邮件交换器 (RFC7505)。真的,唯一的办法就是给他们发一封带有号召性用语链接的邮件,然后等待他们回复……
      【解决方案16】:

      一般来说,验证电子邮件地址的正则表达式并不是一件容易的事情;在撰写本文时,电子邮件地址的语法必须遵循相对较多的标准,而在正则表达式中实现所有这些标准实际上是不可行的!

      我强烈建议您尝试我们的 EmailVerify.NET,这是一个成熟的 .NET 库,它可以根据当前 IETF 标准(RFC 1123、RFC 2821、RFC 2822、RFC 3696)所有验证电子邮件地址、RFC 4291、RFC 5321 和 RFC 5322),测试相关的 DNS 记录,检查目标邮箱是否可以接受邮件,甚至可以判断给定地址是否是一次性的。

      免责声明:我是该组件的首席开发人员。

      【讨论】:

      • 令人印象深刻! “接下来,它会尝试联系负责给定电子邮件地址的邮件交换器,并与该服务器开始一个虚假的 SMTP 对话,模拟真实的邮件服务器。这样可以确保服务器可以处理该地址的电子邮件。实际上有许多 SMTP 服务器回复误报答案以防止垃圾邮件发送者:为了克服这个问题,.NET 的 EmailVerify 最终尝试使用不同的伪造地址多次查询目标邮件交换器。"
      • 谢谢,@MatthewLock ;)
      • 不错,但我只看到付费版本。有社区/开源版本的计划吗?
      • @OhadSchneider 是的:我们通过 Verifalia(我们的 SaaS email verification service)提供电子邮件验证技术的免费版本。 Verifalia 为主要软件开发平台提供免费和开源的 SDK,包括 .NET
      【解决方案17】:
      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 验证为有效的电子邮件地址。
      【解决方案18】:

      如果您使用FluentValidation,您可以编写如下简单的内容:

      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;
      

      【讨论】:

        【解决方案19】:

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

        【讨论】:

        • 这似乎没有帮助...Console.WriteLine(MailAddress("asdf@asdf.").Address); 输出“asdf@asdf.”,这是无效的。
        • .net 似乎有自己的有效定义。相关discussion
        【解决方案20】:

        这里有很多强有力的答案。但是,我建议我们退后一步。 @Cogwheel 回答了https://stackoverflow.com/a/1374644/388267 的问题。然而,如果正在验证的许多电子邮件地址无效,则在批量验证方案中成本可能很高。我建议我们在进入他的 try-catch 块之前使用一些逻辑。我知道可以使用 RegEx 编写以下代码,但是对于新开发人员来说理解起来可能会很昂贵。这是我的两便士:

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

        【讨论】:

          【解决方案21】:

          @Cogwheel 投票最多的答案是最佳答案,但是我尝试实现trim() 字符串方法,因此它将修剪从字符串开始到结束的所有用户空白。查看下面的代码以获取完整示例-

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

          【讨论】:

          • 这样做的风险是您正在验证与源不同的电子邮件地址,让您认为您可以邮寄到(在这种情况下)未修剪版本的指定电子邮件地址。更好的方法是创建一个单独的方法SanitizeEmail(string email),使用该方法的结果来验证电子邮件并将其发送到。
          【解决方案22】:

          另一个正则表达式匹配答案:

             /// <summary>
             /// Validates the email input
             /// </summary>
             internal static bool ValidateEmail(string _emailAddress)
             { 
          
                  string _regexPattern = @"^(([\w-]+\.)+[\w-]+|([a-zA-Z]{1}|[\w-]{2,}))@"
                          + @"((([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\."
                          + @"([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])\.([0-1]?[0-9]{1,2}|25[0-5]|2[0-4][0-9])){1}|"
                          + @"([a-zA-Z]+[\w-]+\.)+[a-zA-Z]{2,4})$";
          
                  return (string.IsNullOrEmpty(_emailAddress) == false && System.Text.RegularExpressions.Regex.IsMatch(_emailAddress, _regexPattern))
                      ? true
                      : false;
              }
          

          【讨论】:

            【解决方案23】:

            正如许多答案中提到的,电子邮件地址的域很复杂。在这种情况下,我强烈反对使用正则表达式。那些匹配(大多数)案例的人非常难以阅读和维护。此外,仍然难以支持所有案例,而且速度很慢。

            Microsoft 的EmailAddress 类在这方面有所帮助,但我认为也不完美。对于一个开源项目,我在几年前尝试过,使用自定义的EmailParser

            用于 [EmailAddress]https://github.com/Qowaiv/Qowaiv/blob/master/src/Qowaiv/EmailAddress.cs)。

            通过使用这种方法,您不仅可以验证电子邮件地址,还可以清除多种格式的显示名称、摆脱 mailto:-前缀,以及基于 IP 地址规范化域文字,以及小写所有内容(请注意,本地部分正式区分大小写)。

            您的解决方案应该支持的场景(并且提到的支持):

            [TestCase(null)]
            [TestCase("")]
            [TestCase("..@test.com")]
            [TestCase(".a@test.com")]
            [TestCase("ab@sd@dd")]
            [TestCase(".@s.dd")]
            [TestCase("ab@988.120.150.10")]
            [TestCase("ab@120.256.256.120")]
            [TestCase("ab@120.25.1111.120")]
            [TestCase("ab@[188.120.150.10")]
            [TestCase("ab@188.120.150.10]")]
            [TestCase("ab@[188.120.150.10].com")]
            [TestCase("a@b.-de.cc")]
            [TestCase("a@bde-.cc")]
            [TestCase("a@bde.c-c")]
            [TestCase("a@bde.cc.")]
            [TestCase("ab@b+de.cc")]
            [TestCase("a..b@bde.cc")]
            [TestCase("_@bde.cc,")]
            [TestCase("plainaddress")]
            [TestCase("plain.address")]
            [TestCase("@%^%#$@#$@#.com")]
            [TestCase("@domain.com")]
            [TestCase("Joe Smith &lt;email@domain.com&gt;")]
            [TestCase("email.domain.com")]
            [TestCase("email@domain@domain.com")]
            [TestCase(".email@domain.com")]
            [TestCase("email.@domain.com")]
            [TestCase("email..email@domain.com")]
            [TestCase("email@-domain.com")]
            [TestCase("email@domain-.com")]
            [TestCase("email@domain.com-")]
            [TestCase("email@.domain.com")]
            [TestCase("email@domain.com.")]
            [TestCase("email@domain..com")]
            [TestCase("email@111.222.333")]
            [TestCase("email@111.222.333.256")]
            [TestCase("email@[123.123.123.123")]
            [TestCase("email@[123.123.123].123")]
            [TestCase("email@123.123.123.123]")]
            [TestCase("email@123.123.[123.123]")]
            [TestCase("email@{leftbracket.com")]
            [TestCase("email@rightbracket}.com")]
            [TestCase("email@p|pe.com")]
            [TestCase("isis@100%.nl")]
            [TestCase("email@dollar$.com")]
            [TestCase("email@r&amp;d.com")]
            [TestCase("email@#hash.com")]
            [TestCase("email@wave~tilde.com")]
            [TestCase("email@exclamation!mark.com")]
            [TestCase("email@question?mark.com")]
            [TestCase("email@obelix*asterisk.com")]
            [TestCase("email@grave`accent.com")]
            [TestCase("email@colon:colon.com")]
            [TestCase("email@caret^xor.com")]
            [TestCase("email@=qowaiv.com")]
            [TestCase("email@plus+.com")]
            [TestCase("email@domain.com>")]
            [TestCase("email( (nested) )@plus.com")]
            [TestCase("email)mirror(@plus.com")]
            [TestCase("email@plus.com (not closed comment")]
            [TestCase("email(with @ in comment)plus.com")]
            [TestCase(@"""Joe Smith email@domain.com")]
            [TestCase(@"""Joe Smith' email@domain.com")]
            [TestCase(@"""Joe Smith""email@domain.com")]
            [TestCase("email@mailto:domain.com")]
            [TestCase("mailto:mailto:email@domain.com")]
            [TestCase("Display Name <email@plus.com> (after name with display)")]
            [TestCase("ReDoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
            public void IsInvalid(string email)
            {
                Assert.IsFalse(EmailAddress.IsValid(email), email);
            }
            
            [TestCase("w@com")]
            [TestCase("w.b.f@test.com")]
            [TestCase("w.b.f@test.museum")]
            [TestCase("a.a@test.com")]
            [TestCase("ab@288.120.150.10.com")]
            [TestCase("ab@188.120.150.10")]
            [TestCase("ab@1.0.0.10")]
            [TestCase("ab@120.25.254.120")]
            [TestCase("ab@01.120.150.1")]
            [TestCase("ab@88.120.150.021")]
            [TestCase("ab@88.120.150.01")]
            [TestCase("ab@[120.254.254.120]")]
            [TestCase("local@2001:0db8:85a3:0000:0000:8a2e:0370:7334")]
            [TestCase("local@[2001:0db8:85a3:0000:0000:8a2e:0370:7334]")]
            [TestCase("2@bde.cc")]
            [TestCase("-@bde.cc")]
            [TestCase("a2@bde.cc")]
            [TestCase("a-b@bde.cc")]
            [TestCase("ab@b-de.cc")]
            [TestCase("a+b@bde.cc")]
            [TestCase("f.f.f@bde.cc")]
            [TestCase("ab_c@bde.cc")]
            [TestCase("_-_@bde.cc")]
            [TestCase("k.haak@12move.nl")]
            [TestCase("K.HAAK@12MOVE.NL")]
            [TestCase("email@domain.com")]
            [TestCase("email@domain")]
            [TestCase("あいうえお@domain.com")]
            [TestCase("local@あいうえお.com")]
            [TestCase("firstname.lastname@domain.com")]
            [TestCase("email@subdomain.domain.com")]
            [TestCase("firstname+lastname@domain.com")]
            [TestCase("email@123.123.123.123")]
            [TestCase("email@[123.123.123.123]")]
            [TestCase("1234567890@domain.com")]
            [TestCase("a@domain.com")]
            [TestCase("a.b.c.d@domain.com")]
            [TestCase("aap.123.noot.mies@domain.com")]
            [TestCase("1@domain.com")]
            [TestCase("email@domain-one.com")]
            [TestCase("_______@domain.com")]
            [TestCase("email@domain.topleveldomain")]
            [TestCase("email@domain.co.jp")]
            [TestCase("firstname-lastname@domain.com")]
            [TestCase("firstname-lastname@d.com")]
            [TestCase("FIRSTNAME-LASTNAME@d--n.com")]
            [TestCase("first-name-last-name@d-a-n.com")]
            [TestCase("{local{name{{with{@leftbracket.com")]
            [TestCase("}local}name}}with{@rightbracket.com")]
            [TestCase("|local||name|with|@pipe.com")]
            [TestCase("%local%%name%with%@percentage.com")]
            [TestCase("$local$$name$with$@dollar.com")]
            [TestCase("&local&&name&with&$@amp.com")]
            [TestCase("#local##name#with#@hash.com")]
            [TestCase("~local~~name~with~@tilde.com")]
            [TestCase("!local!!name!with!@exclamation.com")]
            [TestCase("?local??name?with?@question.com")]
            [TestCase("*local**name*with*@asterisk.com")]
            [TestCase("`local``name`with`@grave-accent.com")]
            [TestCase("^local^^name^with^@xor.com")]
            [TestCase("=local==name=with=@equality.com")]
            [TestCase("+local++name+with+@equality.com")]
            [TestCase("Joe Smith <email@domain.com>")]
            [TestCase("email@domain.com (joe Smith)")]
            [TestCase(@"""Joe Smith"" email@domain.com")]
            [TestCase(@"""Joe\\tSmith"" email@domain.com")]
            [TestCase(@"""Joe\""Smith"" email@domain.com")]
            [TestCase(@"Test |<gaaf <email@domain.com>")]
            [TestCase("MailTo:casesensitve@domain.com")]
            [TestCase("mailto:email@domain.com")]
            [TestCase("Joe Smith <mailto:email@domain.com>")]
            [TestCase("Joe Smith <mailto:email(with comment)@domain.com>")]
            [TestCase(@"""With extra < within quotes"" Display Name<email@domain.com>")]
            [TestCase("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")]
            public void IsValid(string email)
            {
                Assert.IsTrue(EmailAddress.IsValid(email), email);
            }
            

            【讨论】:

              【解决方案24】:
              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);
              }
              

              【讨论】:

                【解决方案25】:

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

                【讨论】:

                  【解决方案26】:

                  /使用用于创建“new EmailAddressAttribute();”的内部正则表达式.Net4.5 中的组件 >>> 使用 System.ComponentModel.DataAnnotations; //验证电子邮件地址......经过测试和工作。

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

                  另外,你可以使用这个:

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

                  【讨论】:

                  • 这封电子邮件说的是真的:“fulya_42_@hotmail.coö”,它在 mandrill api 处抛出错误
                  • 首先,电子邮件有效 w.r.t。 example@example.co 或 example@example.com....除了最后一个字符“ö”外,电子邮件具有所有有效的字符串和条件,您可以轻松添加一个简单的条件来验证此类字符。其次,我不确定 mandrill api 错误,你可能想验证你的使用方法,因为我已经在其他一些环境/api 上使用了这个验证,它对我很好。
                  【解决方案27】:

                  我将 Poyson 1 的回答简化如下:

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

                  【讨论】:

                    【解决方案28】:

                    识别emailid是否有效的简单方法。

                    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})(\]?)$");
                    }
                    

                    【讨论】:

                      【解决方案29】:

                      C# 中的正则表达式存在文化问题,而不是 js。所以我们需要在美国模式下使用正则表达式进行电子邮件检查。如果您不使用 ECMAScript 模式,您的语言特殊字符会在 A-Z 中使用正则表达式来暗示。

                      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)
                      

                      【讨论】:

                        【解决方案30】:

                        我最终使用了这个正则表达式,因为它成功地验证了逗号、cmets、Unicode 字符和 IP(v4) 域地址。

                        有效地址为:

                        " "@example.org

                        (评论)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,}))$";
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2014-06-12
                          • 1970-01-01
                          • 2013-03-25
                          • 2018-03-13
                          • 2011-09-02
                          • 2013-02-20
                          • 2014-03-12
                          • 1970-01-01
                          相关资源
                          最近更新 更多