System.Net.MailMessage允许一些无效的电子邮件地址格式

许多人可能已经意识到,正确validation电子邮件地址可能有点噩梦。 您可以整天搜索与当前RFC标准匹配的C#正则表达式,并且您将找到可以提供不同结果的不同正则表达式。

如果查看http://en.wikipedia.org/wiki/Email_address#Local_part ,您将看到不允许在本地部分的开头或结尾处出现句点。 也不允许连续两个时期。 但是,以下NUnit测试certificateSystem.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;gi[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.comtest..example@example.com无法抛出System.FormatException? 谁在这里错了,微软还是维基百科? 是否有任何电子邮件地址被允许进入允许尾随期或双期? 我的validation应该允许吗? 我有适当的exception处理,以便在发生exception时允许我的电子邮件传递服务继续进行当天,但我想丢弃无效或保证会抛出exception的电子邮件地址。

没有解释原因,但MSDN在System.Net.Mail.MailAddress上的文档调用了这种地址格式:

MailAddress类支持以下邮件地址格式:

  • 用户名中的连续点和尾随点。 例如,user … name .. @ host。

所以它不是MailAddress类中的错误 – 该表单是明确支持的。 但我不知道支持他们的原因是什么。 我假设某些系统可能实际上接受它们,MS认为需要支持这种情况。

另一方面,虽然我可以理解需要对电子邮件地址进行一些validation,但我个人认为在validation中几乎不需要超级严格。 无论如何,系统需要处理坏的,但语法上有效的地址。 另一方面,看起来像本地部分末尾的加倍时段或句号可能是一个常见的拼写错误,所以我可以理解为什么你可能希望它们失败validation。

好吧,既然RFC定义了标准,那么微软的实现就是错误的。

如果您想进行更好的validation,请尝试我在 C#电子邮件地址validation问题的答案中发布的validation器 。

它应该(并且严格地)validation您可能遇到的local-part @域格式的几乎任何“正常”电子邮件地址,尽管它不会处理允许的新的非ASCII样式内容。 我不保证自从几年前就有一点点腐烂并且自我写完以来电子邮件RFC已经更新了。

本地部分必须不加引号:它不支持引用的本地部分或引用的标签。

就域名部分而言,我的validation器不支持IPv4或IPv6文字(尽管添加它并不困难)。

如果要允许任何/所有符合RFC的地址,则会变得更加困难。