检查电子邮件地址是否有效,以用于System.Net.Mail.MailAddress。

38

目前,为了避免因为无效的电子邮件地址而抛出错误,我会采取以下措施:

Dim mailAddress As MailAddress
Try
   mailAddress = New MailAddress("testing@invalid@email.com")
Catch ex As Exception
   'Invalid email
End Try

然而,是否有一种验证电子邮件地址对于MailAddress类型将是100%有效的方式,而不是依赖于Try..Catch

我知道有很多正则表达式函数可以用来验证电子邮件,但我正在寻找MailAddress类型用于验证其地址的函数。


你尝试使用反编译器查看 MailAddress 使用了什么吗? - Oded
1
@Oded:我有。它使用一个名为MailBnfHelper的大型内部类,在.Net 4.0中发生了重大变化。我不建议提取它。 - SLaks
不同版本的.Net框架使用不同的规则来支持它,因此我担心您创建的任何正则表达式可能不具备未来性。Try Catch将是具有未来性的,所以我同意SLaks的答案。否则,如果您真的想编写一个正则表达式,MailAddress的文档描述了它使用的规则,因此您可以将其用作起点。 - Hans Olsson
@ho:你不能使用正则表达式。电子邮件地址不构成一个正则语言。 - SLaks
4
通常情况下,这不是一个好的做法,但在这种情况下,这是最好的可用选项。 - SLaks
显示剩余2条评论
6个回答

40

很遗憾,没有MailAddress.TryParse方法。

您的代码是在.Net中验证电子邮件地址的理想方式。


2
我不同意这个观点,我认为使用正则表达式比使用try/catch块更好,因为后者通常很慢。 - Cromat
4
@Cromat: 错了。正则表达式也很慢,任何足够复杂以逼近电子邮件地址的正则表达式都将非常慢。此外,catch块只有在实际捕获异常时才会变慢,因此在常见情况下有效地址不会减慢任何速度。 - SLaks
2
@Oded 不,它们不是最快的东西,然而使用异常来控制应用程序流程从来都不是一个好的实践。 - Cromat
8
@Cromat - 正确,应该避免使用异常来进行控制流程。但是我们也需要知道何时违反这个规则(不是故意用双关语)。 - Oded
1
@Cromat 只是提供信息:Microsoft在如何:验证字符串是否为有效的电子邮件格式中提供了一个“推荐”的正则表达式来完成此任务。但是,在他们解释RegEx的工作原理之后,他们加入了“而不是使用正则表达式验证电子邮件地址,您可以使用System.Net.Mail.MailAddress类。” :) 因此,即使是微软自己的RegEx,MS也更喜欢在MailAddress周围使用try/catch。 - Solomon Rutzky
显示剩余4条评论

8

但是 MailAddressCollection.TryCreate()TryAdd(),多地址的等价方法在哪里呢?当我们只使用抛出异常的方法时,可以通过 new MailAddress(value)new MailAddressCollection().Add(valueOrValues) 来区分单个和多个(逗号分隔)地址。他们是否忽略了后者的布尔值返回变体? - Timo
@Timo 我猜对象创建和集合初始化/填充是两个不同的事情,因此它们有不同的方法。TryCreate 逻辑上指的是创建空的 MailAddressCollection 本身,即使它存在,也可能没有什么用处,因为您不会得到任何指示哪个提供的电子邮件是错误的(?)。然而,这只是我的个人看法,纯粹的事实是从源代码中我所看到的没有这样的等价物。 - seekingtheoptimal

5
如果您需要确保所提供的电子邮件地址符合IETF标准-此时MailAddress类似乎只部分遵循-我建议您查看EmailVerify.NET,这是一个.NET组件,您可以轻松将其集成到解决方案中。它不依赖于正则表达式来执行其工作,而是依靠内部有限状态机,因此速度非常快。 免责声明:我是该组件的主要开发人员。

6
这个组件不是免费的 - 它售价50.00美元。 - bgmCoder
不通过 NuGet 获得该方法通常是一个警告信号。并且为了验证电子邮件地址而支付费用是不必要的。 - pianocomposer

1

虽然不是针对这个问题的答案,但如果有人需要的话,我编写了一个使用此方法验证电子邮件地址的C#函数。

FixEmailAddress("walter@xyz.com")

returns "walter@xyz.com"

FixEmailAddress("wa@lter@xyz.com,tom@xyz.com,asdfdsf,vsav-sdfsd@xyz.xyz")

返回 "tom@xyz.com,vsav-sdfsd@xyz.xyz"

我这样处理电子邮件地址列表,因为逗号分隔的电子邮件列表是MailAddressCollection.Add()的有效参数。

/// <summary>
/// Given a single email address, return the email address if it is valid, or empty string if invalid.
/// or given a comma delimited list of email addresses, return the a comma list of valid email addresses from the original list.
/// </summary>
/// <param name="emailAddess"></param>
/// <returns>Validated email address(es)</returns>  
public static string FixEmailAddress(string emailAddress)
{

   string result = "";

    emailAddress = emailAddress.Replace(";",",");
   if (emailAddress.Contains(","))
   {
       List<string> results = new List<string>();
       string[] emailAddresses = emailAddress.Split(new char[] { ',' });
       foreach (string e in emailAddresses)
       {
           string temp = FixEmailAddress(e);
           if (temp != "")
           {
               results.Add(temp);
           }
       }
       result = string.Join(",", results);
   }
   else
   {

       try
       {
           System.Net.Mail.MailAddress email = new System.Net.Mail.MailAddress(emailAddress);
           result = email.Address;
       }
       catch (Exception)
       {
           result = "";
       }

   }

   return result;

}


1

0

一些字符在某些服务提供商中是有效的,但在其他服务提供商中则不是!SmtpClient 不知道任何关于服务提供商的信息。因此,它必须尽可能少地过滤。Wikipedia 很好地提到了标准。

MailAddress 的验证在 MSDN 中有提到。因此,在初始化 MailAddress 之前,我认为您可以检查这些验证。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接