许多人可能已经意识到,正确验证电子邮件地址可能有点像噩梦。您可以整天搜索与当前RFC标准匹配的C#正则表达式,并且您将找到不同结果的不同正则表达式。
如果查看http://en.wikipedia.org/wiki/Email_address#Local_part,您将看到不允许在本地部分的开头或结尾处出现句点。也不允许连续两个时期。但是,以下NUnit测试证明System.Net.MailMessage允许您为某些无效的电子邮件地址格式实例化MailMessage对象。
[Test]
[TestCase(@"foobar@exampleserver")] //technically valid from the wiki article
[TestCase(@"jsmith@[192.168.2.1]")] //technically valid from the wiki article
[TestCase(@"niceandsimple@example.com")] //vanilla email address
[TestCase(@"very.common@example.com")] //also standard
[TestCase(@"a.little.lengthy.but.fine@dept.example.com")] //long with lots of periods
[TestCase(@"disposable.style.email.with+symbol@example.com")] //disposable with the + symbol
[TestCase(@"other.email-with-dash@example.com")] //period and dash in local part
[TestCase(@"user-test-hyphens@example-domain.com")] //lots of hyphens
[TestCase(@"!#$%&'*+-/=?^_`{|}~@example-domain.com")] //all these symbols are allowed in local part
[TestCase(@"ër_%لdev@gكňil.com")] //characters outside the ascii range are permitted
[TestCase(@"""abcdefghixyz""@example.com")] //technically valid
//[TestCase(@"abc.""defghi"".xyz@example.com")] //technically valid, but .NET throws exception
public void CanCreateMailMessageObjectTest(string emailAddress)
{
var mailMessage = new System.Net.Mail.MailMessage("noreply@example.com", emailAddress);
}
除了最后一个测试用例之外,所有上述测试用例都通过了。
[Test]
[TestCase(@".test@example.com")] //leading period
[TestCase(@"test.@example.com")] //period at end of local part <---FAIL
[TestCase(@"test..example@example.com")] //double period in local part <---FAIL
[TestCase(@"foobar@example!#$%^&*()=server.com")] //special characters in domain part
[TestCase(@"Abc.example.com")] //No @ separating local and domain part
[TestCase(@"A@b@c@example.com")] //more than one @ symbol
[TestCase(@"just""not""right@example.com")] //quoted strings must be dot separated
[TestCase(@"a""b(c)d,e:f;g<h>i[j\k]l@example.com")] //special symbols "(),:;<>@[\] not inside quotes
[TestCase(@"[test@example.com")] //leading special symbol in local part
[TestCase(@"this is""not\allowed@example.com")] //spaces not in quotes
[TestCase(@"this\ still\""not\\allowed@example.com")] //backslashes not in quotes
[ExpectedException(typeof (System.FormatException))]
public void CannotCreateMailMessageObjectTest(string emailAddress)
{
var mailMessage = new System.Net.Mail.MailMessage("noreply@example.com", emailAddress);
}
为什么test.@example.com
和test..example@example.com
无法抛出System.FormatException?谁在这里错了,微软还是维基百科?是否有任何电子邮件地址被允许进入允许尾随期或双期?我的验证应该允许吗?我有适当的异常处理,以便在发生异常时允许我的电子邮件递送服务继续进行当天,但我想丢弃无效或保证会抛出异常的电子邮件地址。
答案 0 :(得分:3)
没有解释原因,但MSDN's docs on System.Net.Mail.MailAddress
提出支持此地址格式:
MailAddress类支持以下邮件地址格式:
...
- 用户名中的连续点和尾随点。例如,user ... name .. @ host。
所以它不是MailAddress
类中的错误 - 该表单是明确支持的。但我不知道支持他们的原因是什么。我假设某些系统可能实际接受它们,而MS认为需要支持这种情况。
另一方面,虽然我可以理解需要对电子邮件地址进行一些验证,但我个人认为在验证中几乎不需要超级严格。无论如何,系统需要处理坏的,但语法上有效的地址。另一方面,在本地部分结尾处看起来像是一个加倍的句号或句号可能是一个常见的拼写错误,所以我可以理解为什么你可能希望它们无法通过验证。
答案 1 :(得分:0)
好吧,既然RFC定义了标准,那么微软的实现就是错误的。
如果您想进行更好的验证,请尝试问题validator I posted in this answer的C# Email Address validation。
它应该(并且严格地)验证几乎任何&#34;正常&#34;您可能会遇到的格式 local-part @ domain 的电子邮件地址,但它不会处理允许的新的非ASCII样式内容。我不保证自从几年前就有一点点腐烂并且自我写完以来电子邮件RFC已经更新。
local-part 必须是不加引号的:它不支持引用的local-parts或带引号的标签。
就域名部分而言,我的验证器不支持IPv4或IPv6文字(尽管添加它并不困难)。
如果您想允许任何/所有符合RFC的地址,则会变得更加困难。